Modèle de domaine partagé entre différents microservices

61

Imaginez un scénario de deux microservices différents. L’un pour gérer l’authentification au sein du service, l’autre pour la gestion des utilisateurs. Ils ont tous deux un concept d'utilisateur et parleront d'utilisateurs par le biais d'appels mutuels.

À quel domaine appartiendrait le modèle de domaine d'un "utilisateur"? Auraient-ils tous deux une représentation différente de ce qu'un utilisateur est au niveau de la base de données? Qu'en est-il lorsque nous avons un UserDTO à utiliser dans les appels d'API, les deux en ont-ils un pour leurs API respectives?

Quelle est la solution généralement acceptée pour ce type de problème architectural?

Kristof
la source

Réponses:

36

Dans une architecture Microservices, chacun est absolument indépendant des autres et doit masquer les détails de la mise en œuvre interne.

Si vous partagez le modèle, vous couplez des microservices et vous perdez l’un des plus grands avantages pour lesquels chaque équipe peut développer son microservice sans restrictions et sans avoir besoin de savoir comment évoluer les autres microservices. N'oubliez pas que vous pouvez même utiliser différentes langues dans chacune d'elles. Cela serait difficile si vous commenciez à coupler des microservices.

S'ils sont trop liés les uns aux autres, peut-être en sont-ils vraiment un, comme le dit @soru.

Questions connexes:

gabrielgiussi
la source
21
Je ne peux pas être tout à fait d’accord, s’ils sont complètement indépendants, vous avez 2 monolithes. L'idée est d'avoir des terminaux intelligents et des canaux muets. Dans le contexte de l'entreprise, vous vous retrouvez (actuellement mon cauchemar) au mur car il existe un modèle de domaine commun implicite (implicite car nous ne l'avions pas prévu) et chaque service réinvente un% de la roue. Et l'écosystème de micro-services se développe avec un accent mis à 100% sur la fonctionnalité et la propriété des équipes, ce qui gâche le problème avec le modèle de domaine. Nous avons des équipes qui créent de nouveaux services, en consomment d’autres, dupliquent beaucoup d’efforts. Toujours pas résolu.
juanmf
5
Nous avons également laissé de côté une très importante architecture: Performance, Exigence non fonctionnelle significative. Ces services nécessitant la sortie d'autres services, traduisent une approche de communication à plusieurs niveaux pour chaque QR client. Ajout de latence qui ne peut pas être traitée à moins d’un refactoriseur lourd et éventuellement d’une fusion de micro-services.
juanmf
3
De plus, le fait de ne pas avoir une compréhension commune du modèle de domaine a incité les équipes à appliquer des "transformations unmarshalling + objet-objet" inutiles pour adapter les réponses de micro-services au modèle adopté par le micro-service appelant. Je sais que le couplage de tous les services à un modèle de domaine commun lib peut poser d’autres problèmes opérationnels, mais je ne trouve aucune solution satisfaisante.
juanmf
3
@juanmf Il serait très utile de pouvoir poser une question sur vos problèmes. Je suis également intéressé par les opinions sur ce sujet ...
Milos Mrdovic
1
Je vais essayer de m'asseoir et d'écrire quelque chose qui a du sens
juanmf
13

Si deux services sont suffisamment imbriqués au point qu'il serait difficile de les implémenter sans partager les objets DTO et les autres objets modèles, c'est un signe fort que vous ne devriez pas avoir deux services.

Certes, l'exemple n'a pas de sens en tant que deux services; Il est difficile d'imaginer une spécification pour la «gestion des utilisateurs» si compliquée que toute une équipe soit si occupée qu'elle n'a pas le temps de s'authentifier.

Si pour une raison quelconque ils l'étaient, ils communiqueraient en utilisant des chaînes fondamentalement arbitraires, comme dans OAuth 2.0 .

soru
la source
4

Vous pouvez les considérer comme deux contextes délimités distincts (dans le jargon de la conception par domaine). Ils ne doivent partager aucune donnée entre eux, mis à part un identifiant utilisé pour corréler "l'utilisateur" du contexte d'authentification avec "l'utilisateur" de l'autre contexte. Ils peuvent chacun avoir leur propre représentation de ce qu'est un "utilisateur" et leur propre modèle de domaine, qui ne contient que les informations nécessaires pour s'acquitter de leur responsabilité professionnelle.

N'oubliez pas qu'un modèle de domaine n'essaie pas de modéliser une "chose" du monde réel, mais sa nature dans un contexte particulier (tel que Gestion de l'identité / des autorisations ou des ressources humaines, etc.).

pnschofield
la source
2

Ils ont tous deux un concept d'utilisateur et parleront d'utilisateurs par le biais d'appels mutuels.

Je suis également d'accord avec ce que @soru a dit. Si un service a besoin des données d'un autre service, ses limites sont fausses.

Une solution intéressante est ce que @pnschofield a proposé: traiter vos services comme un contexte limité.

En quelques mots, les modèles de domaine partagé nuisent à l’autonomie du service et transforment votre système de microservice en monolith distribué. Ce qui est apparemment encore pire qu'un monolithe.

Il reste donc une question générale non résolue: comment définir les limites de service ou de contexte afin qu’elles se développent avec une cohésion élevée et une qualité de couplage lâche.

J'ai mis au point une solution pour traiter mes contextes comme une capacité métier. Il s'agit d'une fonctionnalité métier de niveau supérieur de responsabilité professionnelle contribuant à la réalisation de l'objectif global de l'entreprise. Vous pouvez les considérer comme des étapes que votre organisation doit suivre pour obtenir une valeur commerciale.

La séquence typique d'étapes que je fais lors de l'identification des limites de service est la suivante:

  1. Identifiez les capacités professionnelles de niveau supérieur. Ils sont généralement similaires parmi les organisations du même domaine. Vous pouvez avoir une idée de ce à quoi cela ressemble de vérifier le modèle de chaîne de valeur de Porter .
  2. Dans chaque capacité, approfondissez et identifiez les sous-capacités.
  3. Notez la communication entre les capacités. Regardez ce que fait une organisation. Habituellement, la communication est concentrée dans les capacités, informant les autres du résultat de ses travaux. Ainsi, lors de la mise en œuvre de l'architecture technique, votre service doit également communiquer via des événements. Cela a de multiples conséquences positives. Avec cette approche, vos services sont autonomes et cohérents. Ils n'ont pas besoin de communication synchrone ni de transactions distribuées.

Probablement un exemple de cette technique pourrait vous intéresser. N'hésitez pas à me dire ce que vous pensez, car j'ai trouvé cette approche vraiment rentable. Bien sûr, cela peut marcher pour vous aussi.

Zapadlo
la source
1

Microservice ne consiste pas à "ne rien partager", mais à "partager le moins possible". Dans la plupart des cas, "utilisateur" est une entité vraiment commune (simplement parce que l'utilisateur est identifié par un identificateur partagé - ID utilisateur / courrier électronique / téléphone). Ce genre d'entités partagées par définition. Le modèle utilisateur est hors de portée du microservice. Vous devez donc avoir un schéma global dans lequel l'utilisateur (uniquement leurs champs les plus courants) doit être placé. Dans le cas strict est id seulement.

Evgeniy Ostapenko
la source