Utilisation de l'analyse de domaine pour modéliser les microservices

L’un des plus grandes problématiques des microservices est la définition des limites de chacun des services isolés. Le principe de base est qu’un service doit exécuter « une action ». Toutefois, l’application concrète de cette règle nécessite une réflexion approfondie. Aucun processus mécanique ne produira la conception idéale. Vous devez analyser en profondeur le domaine, les exigences et les objectifs de votre entreprise. Sinon, vous pouvez avoir à gérer une conception incohérente présentant des caractéristiques indésirables, comme des dépendances masquées entre les services, un couplage étroit ou des interfaces mal développées. Ce chapitre présente une approche orientée domaine de la conception des microservices.

Cet article utilise l'exemple d'un service de livraison par drone. Pour en savoir plus sur le scénario et l'implémentation de référence correspondante, cliquez ici.

Introduction

Les microservices doivent être alignés sur les activités commerciales, pas développés comme des couches horizontales de données, telles que l’accès aux données ou la messagerie. Par ailleurs, ils doivent présenter un couplage souple et une haute cohérence fonctionnelle. Les microservices sont couplés souplement si vous êtes en mesure de modifier un service sans avoir à mettre à jour d’autres services au même moment. Un microservice est cohérent s’il a une vocation unique et précisément définie, comme la gestion des comptes utilisateurs ou le suivi de l’historique de livraison. Un service a vocation à encapsuler la connaissance du domaine et à extraire cette connaissance des clients. Par exemple, un client doit pouvoir programmer un drone sans connaître en détail l’algorithme de programmation ni maîtriser la gestion de la flotte de drones.

La conception pilotée par domaine fournit une infrastructure constituant la base d’un ensemble efficacement organisé de microservices. Cette approche comporte deux phases distinctes, l’une stratégique, l’autre tactique. Dans la phase stratégique de la conception pilotée par domaine, vous définissez la structure à grande échelle du système. Cette phase garantit que votre architecture demeure axée sur les fonctionnalités commerciales. La phase tactique, quant à elle, offre un jeu de modèles de conception à valoriser pour créer le modèle du domaine. Ces modèles comprennent les entités, les agrégats et les services de domaine. Ces modèles tactiques vous aident à concevoir des microservices à la fois cohérents et souplement couplés.

Diagramme d’un processus DDD (conception basée sur le domaine)

Dans cet article et dans le suivant, nous allons nous intéresser aux phases suivantes, en les exécutant avec l'application Drone Delivery :

  1. Commencez par analyser le domaine d’entreprise afin d’appréhender les exigences fonctionnelles de l’application. Cette étape produit une description informelle du domaine, qui peut être affinée en un jeu plus formel de modèles de domaine.

  2. Ensuite, définissez les limites de contexte du domaine. Chaque limite de contexte comporte un modèle de domaine représentant un sous-domaine spécifique de l’application dans son ensemble.

  3. Au sein d’une limite de contexte, appliquez des modèles tactiques de la conception pilotée par domaine afin de définir les entités, les agrégats et les services de domaine.

  4. Utilisez les résultats de l’étape précédente pour identifier les microservices dans votre application.

Dans cet article, nous abordons les trois premières étapes, qui sont principalement liées à la conception pilotée par domaine. Dans l'article suivant, nous identifierons les microservices. Toutefois, il est essentiel de se rappeler que la conception pilotée par domaine est un processus continu, itératif. Les limites de services ne sont pas fixes. À mesure de l’évolution d’une application, vous pouvez décider de décomposer un service en sous-services de taille plus réduite.

Notes

Cet article n'a pas vocation à apporter une analyse complète et exhaustive du domaine. Nous tâcherons d'apporter un exemple concis pour illustrer les points principaux. Pour plus d’informations sur la conception pilotée par domaine, nous vous recommandons de lire l’ouvrage d’Eric Evans, Domain-Driven Design (Conception pilotée par domaine), dans lequel le concept fut pour la première fois évoqué. Une autre référence importante est le livre Implementing Domain-Driven Design (Implémentation de la conception pilotée par domaine) de Vaughn Vernon.

Scénario : Livraison par drone

Fabrikam, Inc. veut lancer un service de livraison par drone. La société gère un parc de drones. Les entreprises souscrivent au service, et les utilisateurs peuvent demander à ce qu’un drone vienne récupérer les marchandises à livrer. Lorsqu’un client planifie un enlèvement de colis, un système principal assigne un drone et donne à l’utilisateur un délai de livraison estimé. Une fois la livraison en cours, le client peut suivre la position du drone, avec un ATE mis à jour en permanence.

Ce scénario implique un domaine assez complexe. Certaines entreprises veulent programmer des drones, suivre des colis, gérer les comptes d’utilisateur, ainsi que stocker et analyser les données d’historique. En outre, Fabrikam souhaite commercialiser ce service et effectuer une itération rapidement, en ajoutant des nouvelles fonctionnalités. L’application doit fonctionner à l’échelle du cloud, avec un objectif de niveau de service (SLO) élevé. Fabrikam prévoit également que les diverses parties du système auront des besoins très différents pour le stockage et l’interrogation des données. En s’appuyant sur toutes ces considérations, Fabrikam opte pour une architecture de microservices pour l’application Drone Delivery.

Analyser le domaine

L’application d’une approche de conception pilotée par domaine vous permet de configurer des microservices de manière à ce que chacune des composantes constitue une niche dédiée à une exigence fonctionnelle de l’entreprise. Cela peut vous aider à éviter le piège consistant à développer une conception dictée par les limites organisationnelles ou les choix technologiques.

Avant d’écrire le code, vous devez bénéficier d’une visibilité exhaustive sur le système en cours de création. La conception pilotée par domaine vise dans un premier temps à modeler le domaine d’entreprise et à créer un modèle de domaine. Le modèle de domaine est un modèle théorique du modèle d’entreprise. Il répartit et organise la connaissance du domaine, en fournissant un langage commun pour les développeurs et les experts du domaine.

Commencez par mapper l’ensemble des fonctions d’entreprise et leurs connexions. Il s’agira probablement d’un travail collaboratif impliquant les experts du domaine, les architectes logiciels et d’autres parties prenantes. Il n’est pas nécessaire de recourir à aucun formalisme particulier. Dessinez un schéma ou établissez une esquisse sur tableau blanc.

À mesure que vous enrichissez le schéma, vous pouvez commencer à identifier des sous-domaines distincts. Quelles fonctions sont étroitement liées ? Quelles sont les fonctions au cœur de l’entreprise, quelles sont celles prenant en charge les services auxiliaires ? À quoi ressemble le graphique de dépendance ? Durant cette phase initiale, vous ne vous intéressez pas aux technologies ni aux détails de l’implémentation. Ceci dit, vous devez identifier l’emplacement d’intégration de l’application avec les systèmes externes, tel que le processus CRM, le système de traitement des paiements ou les architectures de facturation.

Exemple : Application de livraison par drone (Drone Delivery)

Après quelques activités d’analyse initiale de domaine, l’équipe Fabrikam est parvenue à établir une esquisse brute décrivant le domaine de l’application Drone Delivery.

Diagramme du domaine de Drone Delivery

  • L’Expédition, au cœur de l’activité, est placée au centre du schéma. Elle est tributaire de l’ensemble des autres éléments du schéma.
  • La Gestion des drones est également cruciale. Une fonctionnalité étroitement liée à la gestion des drones est la réparation des drones ; combinée à l’analyse prédictive, elle permet d’établir un échéancier des périodes d’entretien et de maintenance des drones.
  • L’analyse de l’heure prévue fournit des estimations des horaires de collecte et de livraison.
  • Le modèle de transport tiers permet à l’application de planifier des modes de transport alternatifs en cas d’incapacité du drone à livrer l’intégralité d’un colis.
  • Le partage de drones est une extension possible de l’activité principale. La société peut disposer d’une capacité supérieure de drones sur des intervalles spécifiques, et louer des appareils qui seraient inutilisés sans sa sollicitation. Cette fonctionnalité ne sera pas disponible dans la version initiale.
  • La surveillance vidéo est un autre secteur que l’entreprise pourrait choisir de développer à l’avenir.
  • Les comptes utilisateurs, la facturation et le centre d’appels sont des sous-domaines qui prennent en charge l’activité fondamentale.

Notez qu’à ce stade du processus, nous n’avons encore pris aucune décision ayant trait à l’implémentation ou aux technologies. Certains des sous-systèmes peuvent recourir à des systèmes logiciels externes ou des services tiers. Même dans ce cas, l’application doit interagir avec ces systèmes et services. Aussi, il est important de les inclure dans le modèle de domaine.

Notes

Lorsqu’une application dépend d’un système externe, il existe un risque que le schéma de données ou l’API de ce dernier soient répercutés dans votre application, et compromettent le cas échéant la conception architecturale. Ce cas de figure est recensé en particulier avec les systèmes hérités ne respectant pas forcément les meilleures pratiques modernes et pouvant valoriser des schémas de données complexes ou des API obsolètes. Dans ce cas, il est important de définir une limite précise entre ces systèmes externes et l’application. À cette fin, envisagez d’utiliser le modèle Figuier étrangleur ou le modèle de couche anticorruption.

Définir les limites de contexte

Le modèle de domaine comprend des représentations des composantes réelles (utilisateurs, drones, colis, etc.). Cela ne signifie pas pour autant que chacune des portions du système doive utiliser la même représentation pour une composante donnée.

Par exemple, les sous-systèmes dédiés à la réparation des drones et à l'analyse prédictive doivent représenter de nombreuses caractéristiques physiques des drones, comme l'historique de maintenance, le kilométrage, l'âge, le numéro de modèle, les caractéristiques de performance, etc. Toutefois, lors de la planification d’une livraison, ces éléments importent peu. Le sous-système de planification doit simplement connaître la disponibilité des drones, ainsi que les horaires prévus de collecte et de livraison.

Si nous essayions de développer un modèle unique pour chacun de ces sous-systèmes, cela pourrait s’avérer inutilement complexe. Par ailleurs, l’évolution au fil du temps du modèle serait ralentie, dans la mesure où les modifications devraient être validées par plusieurs équipes travaillant sur des sous-systèmes séparés. Par conséquent, il est souvent préférable de concevoir des modèles séparés qui représentent la même entité réelle (dans ce cas, un drone) dans deux contextes différents. Chaque modèle comporte les fonctions et attributs qui sont nécessaires au sein du contexte considéré.

C’est là que le concept de limites de contexte de la conception pilotée par domaine entre en jeu. Une limite de contexte correspond tout simplement au périmètre, au sein d’un domaine, dans lequel s’applique un modèle de domaine particulier. En considérant le schéma précédent, nous pouvons rassembler les fonctionnalités par modèle de domaine.

Digramme des limites de contexte

Les limites de contexte ne sont pas forcément isolées les unes des autres. Dans ce schéma, les lignes pleines reliant les limites de contexte représentent les points d’interaction entre deux limites de contexte. Par exemple, l’Expédition dépend des Comptes utilisateur au niveau de la collecte des informations sur les clients, et de la Gestion des drones en matière de sollicitation des drones disponibles de la flotte.

Dans son ouvrage Domain Driven Design (Conception pilotée par domaine), Eric Evans décrit plusieurs approches utilisées pour maintenir l’intégrité d’un modèle de domaine interagissant avec une autre limite de contexte. L’un des principes fondamentaux des microservices concerne la communication des services, qui s’effectue via des API précisément définies. Cette approche correspond à deux modèles que M. Evans appelle Open Host Service (Service hôte ouvert) et Published Language (Langage publié). L’idée derrière le Service hôte ouvert, c’est qu’un sous-système définit un protocole formel (API) valorisé par les autres sous-systèmes souhaitant communiquer avec lui. Le modèle de Langage publié prolonge cette philosophie. Il consiste en la publication de l’API dans une forme que d’autres équipes peuvent utiliser pour écrire aux clients. Dans l'article Conception d'API pour les microservices, nous évoquons l'utilisation de la Spécification OpenAPI (anciennement Swagger) afin de définir des descriptions d'interface indépendantes de tout langage pour les API REST, exprimées au format JSON ou YAML.

Pour le reste de cette activité, nous nous intéresserons à la limite de contexte Expédition.

Étapes suivantes

À l'issue de l'analyse d'un domaine, l'étape suivante consiste à appliquer la phase tactique de la conception pilotée par domaine pour définir vos modèles de domaine avec plus de précision.