Je travaille sur un projet dans lequel nous essayons d'appliquer à la fois une conception orientée domaine et REST à une architecture orientée service. Nous ne nous inquiétons pas de la conformité 100% REST; il serait probablement préférable de dire que nous essayons de créer des API HTTP orientées ressources (~ niveau 2 du modèle de maturité REST de Richardson). Néanmoins, nous essayons d'éviter l'utilisation de requêtes HTTP de type RPC, c'est-à-dire que nous essayons d'implémenter nos verbes HTTP conformément à la norme RFC2616 plutôt que d'utiliser la méthode POST
à faire IsPostalAddressValid(...)
, par exemple.
Cependant, mettre l'accent sur cela semble se faire aux dépens de notre tentative d'appliquer une conception pilotée par domaine. Avec seulement GET
, POST
, PUT
, DELETE
et quelques autres méthodes rarement utilisées, nous avons tendance à construire des services Cruddy et services Cruddy ont tendance à avoir des modèles anémiques de domaine.
POST
: Recevoir les données, les valider, les transférer dans les données. GET
: Récupérer les données, les renvoyer. Pas de vraie logique métier là-bas. Nous utilisons également des messages (événements) entre les services, et il me semble que l'essentiel de la logique métier finit par être construit autour de cela.
REST et DDD sont-ils en tension à un certain niveau? (Ou est-ce que je comprends mal quelque chose ici? Peut-être faisons-nous autre chose de mal?) Est-il possible de construire un modèle de domaine fort dans une architecture orientée service tout en évitant les appels HTTP de type RPC?
IsPostalAddressValid(...)
pourrait s’insérer dans "Fournir un bloc de données, tel que le résultat de la soumission d’un formulaire, à un processus de traitement de données"?Réponses:
Première loi de Martin Fowler sur les systèmes distribués: "Ne distribuez pas vos objets!" Les interfaces distantes doivent être à grain grossier et les interfaces internes à grain fin. Souvent, le modèle de domaine riche s'applique uniquement dans un contexte limité .
L'API REST sépare deux contextes différents ayant chacun leur propre modèle interne. Les contextes communiquent via une interface à grain grossier (API REST) utilisant des objets "anémiques" (DTO).
Dans votre cas, il semble que vous tentiez de répartir un contexte sur une limite qui est une API REST. Cela peut conduire à une interface distante fine ou à un modèle anémique. En fonction de votre projet, cela peut poser un problème ou non.
la source
POST a été délibérément conçu pour être "intentionnellement vague"; le résultat d'un POST est spécifique à l'implémentation. Qu'est-ce qui vous empêche de faire ce que font Twitter et les autres concepteurs d'API et de définir chaque méthode POST dans la partie non-CRUD de votre API en fonction de vos besoins spécifiques? POST est le verbe catchall. Utilisez-le lorsqu'aucun des autres verbes ne convient parfaitement à l'opération que vous souhaitez effectuer.
En d'autres termes, votre question pourrait également être posée comme suit: "Les objets" intelligents "encouragent-ils la conception de style RPC?" Même Martin Fowler (qui a inventé le terme "Modèle de domaine anémique") admet que les DTO nus présentent certains avantages:
En ce qui concerne le modèle de maturité Richardson , vous pouvez accéder au niveau 3 sans vous préoccuper des "modèles de domaine anémique". N'oubliez pas que vous ne transférerez jamais le comportement sur le navigateur (à moins que vous n'ayez l'intention d'injecter du code JavaScript dans vos modèles).
REST concerne principalement l’indépendance de la machine; implémentez le modèle REST dans la mesure où vous souhaitez que vos points de terminaison représentent des ressources et que les utilisateurs de votre API puissent facilement accéder à ces ressources et les gérer de manière standard. Si cela semble anémique, alors qu'il en soit ainsi.
Voir aussi
j'ai besoin de plus de verbes
la source
L'API REST n'est qu'un type de couche de présentation. Cela n'a rien à voir avec le modèle de domaine.
La question que vous avez posée découle de votre confusion: vous devez vous adapter les uns aux autres. Vous pas.
Vous mappez votre modèle de domaine sur votre API REST de la même manière que vous mappez votre modèle de domaine sur un SGBDR via un ORM - cette couche de mappage doit exister.
Domaine ← ORM →
Domaine RDBMS ← Cartographie REST → API REST
la source
IMHO Je ne pense pas qu'ils ont tendance à encourager les modèles de domaine anémique (ADM), mais ils vous obligent à prendre un peu de temps et à réfléchir.
Tout d’abord, je pense que la principale caractéristique des SMA est qu’ils ont peu ou pas de comportement. Cela ne veut pas dire que le système n'a pas de comportement, mais qu'il se trouve généralement dans une sorte de classe de service (voir http://vimeo.com/43598193 ).
Et bien sûr, si le comportement n'existe pas dans ADM, que fait-on alors? La réponse est bien sûr les données. Et alors, comment cela mappe-t-il à l'API REST? On peut supposer que les données correspondent au contenu de la ressource et le comportement aux verbes HTTP.
Ainsi, vous disposez de tout ce dont vous avez besoin pour créer un modèle de domaine riche. Vous devez simplement savoir comment les verbes HTTP mappent les opérations de domaine sur les données, puis placez ces opérations dans les mêmes classes qui encapsulent vos données.
Je pense que les personnes qui rencontrent des problèmes ont tendance à avoir du mal à comprendre comment les verbes HTTP correspondent au comportement de leur domaine lorsque le comportement dépasse le simple CRUD, c'est-à-dire lorsqu'il y a des effets secondaires dans d'autres parties du domaine au-delà du domaine. ressource en cours de modification par la requête HTTP. Un moyen de résoudre ce problème consiste à utiliser des événements de domaine ( http://www.udidahan.com/2009/06/14/domain-events-salvation/ ).
la source
Cet article est assez lié au sujet et je crois que répond à votre question.
Un concept de base qui, je pense, répond très bien à votre question, est résumé dans le paragraphe suivant de l'article mentionné:
"Il est très important de faire la distinction entre les ressources de l'API REST et les entités de domaine dans une conception pilotée par le domaine. La conception pilotée par le domaine s'applique à la mise en œuvre (y compris l'implémentation d'API), tandis que les ressources de l'API REST pilotent la conception et le contrat de l'API. Ressource API la sélection ne doit pas dépendre des détails de la mise en œuvre du domaine sous-jacent. "
la source
Plusieurs implémentations raisonnablement réussies que j'ai vues / construites répondent à la question de savoir comment elles mélangent la métaphore verbe + nom en utilisant des méthodes «conviviales pour les entreprises» à grain grossier qui agissent sur les entités.
Ainsi, au lieu de la
getName()
méthode / du service (condamné) , exposezgetPerson()
en transmettant des éléments tels que identificateur-type / ID et en renvoyant l'Person
entité entière .Dans la mesure où les comportements de l'entité Personne dans un tel contexte ne peuvent pas être correctement communiqués (ni peut-être dans un contexte centré sur les données), il est parfaitement raisonnable de définir un modèle de données (par rapport à un objet) pour les paires requête / réponse. les services.
Les services et les verbes définis eux-mêmes ajouteront des comportements, des contrôles et même des règles de transition d'état autorisés par le domaine pour les entités. Par exemple, il y aurait une logique spécifique à un domaine pour ce qui se passe dans l'
transferPerson()
appel de service, mais l'interface elle-même ne définirait que les entités / données d'entrée / sortie sans définir LEUR comportement interne.Je suis en désaccord avec les auteurs qui diraient, par exemple, qu'une implémentation de verbe de transfert appartient à la classe Personne ou associée à un service centré sur la personne. En fait, la méthode de transfert pour a
Person
et ses options (dans cet exemple simple) seraient mieux définies par unCarrier
, dans lequelPerson
ils ne savent même pas quelles méthodes de transfert sont disponibles ni comment se produit le transfert (qui sait comment les réacteurs fonctionnent en tous cas).Cela rend-il l'
Person
entité anémique? Je ne pense pas.Il peut / devrait y avoir une logique à propos de choses propres à une personne qui sont internes à une personne, comme son état de santé, qui ne devrait pas être défini par une classe externe.
Toutefois, selon les cas d'utilisation, il est tout à fait acceptable qu'une classe d'entités ne présente aucun comportement important / pertinent dans certains systèmes, tel qu'un service d'attribution de siège dans un système de transport. Un tel système peut très bien implémenter des services basés sur REST qui traitent des instances Person et des identifiants associés, mais ne définissent / implémentent jamais leurs comportements internes.
la source
Est-ce que votre problème est que vous essayez d'inscrire votre modèle dans le jeu de verbes de base, en utilisant autant que possible le POST?
Ce n'est pas nécessaire - je sais que pour la plupart des gens, REST signifie POST, GET, PUT et DELETE, mais le http rfc indique:
Et des systèmes tels que SMTP utilisent le même style de méthodes à base de verbe, mais avec un ensemble totalement différent.
Donc, il n'y a aucune raison pour que vous utilisiez ceux-ci, vous pouvez utiliser le jeu de verbes que vous préférez (cependant, vous constaterez que vous pouvez faire tout ce dont vous avez besoin dans le 4 de base avec un peu de réflexion). Ce qui distingue REST des autres mécanismes, c’est sa manière apatride et cohérente de mettre en œuvre ces verbes. Vous ne devez pas essayer d’implémenter le système de transmission de messages entre les niveaux car vous n’effectuez pas fondamentalement REST, vous utilisez plutôt un mécanisme de transmission de message, RPC ou de file d’attente de messages qui vous fera certainement perdre les avantages de REST simplicité qui fait que cela fonctionne vraiment bien sur une connexion http).
Si vous voulez un protocole de messagerie complexe et complet, construisez-le (si vous pouvez le faire sur le Web, il existe une raison pour laquelle REST est si populaire), mais sinon, essayez de vous en tenir à la conception architecturale de REST.
la source