API Rest et DDD
Dans mon projet à l'aide de DDD méthodologie.
Le projet a l'ensemble(entité) à Traiter. Cet agrégat a beaucoup de cas d'utilisation.
Pour cet agrégat j'ai besoin de créer une api rest.
Avec la norme: de créer et de supprimer sans problème.
1) CreateDealUseCase(le nom, le prix et beaucoup d'autres params);
POST /rest/{version}/deals/
{
'name': 'deal123',
'price': 1234;
'etc': 'etc'
}
2) DeleteDealUseCase(id)
DELETE /rest/{version}/deals/{id}
Mais que faire avec le reste du cas d'utilisation?
- HoldDealUseCase(id, de la raison);
- UnholdDealUseCase(id);
- CompleteDealUseCase(id, et beaucoup d'autres params);
- CancelDealUseCase(id, amercement, de la raison);
- ChangePriceUseCase(id, newPrice, de la raison);
- ChangeCompletionDateUseCase(id, newDate, amercement, whyChanged);
- etc(total de 20 cas d'utilisation)...
Quelles sont les solutions?
1) Utiliser les verbes:
PUT /rest/{version}/deals/{id}/hold
{
'reason': 'test'
}
Mais! Les verbes ne peuvent pas être utilisés dans l'url(dans le RESTE de la théorie).
2) Utiliser le formulaire de l'état(qui sera après la le cas d'utilisation):
PUT /rest/{version}/deals/{id}/holded
{
'reason': 'test'
}
Personnellement, pour moi, il semble laid. Peut-être que je me trompe?
3) Utilisation 1 METTRE de la demande pour toutes les opérations:
PUT /rest/{version}/deals/{id}
{
'action': 'HoldDeal',
'params': {'reason': 'test'}
}
PUT /rest/{version}/deals/{id}
{
'action': 'UnholdDeal',
'params': {}
}
Il est difficile à gérer dans le backend.
En outre, il est difficile de document. Depuis 1 action a de nombreuses variantes de la demande, à partir de laquelle dépend déjà des réponses spécifiques.
Toutes les solutions ont beaucoup d'inconvénients.
J'ai lu de nombreux articles sur le RESTE sur internet. Partout seulement une théorie, la façon d'être ici avec mon problème?
- Je ne veux pas à déclarer ce qui suit à titre de réponse, alors peut-être que d'autres peuvent donner leur avis dans le cas où il est une idée terrible. Que diriez-vous:
/rest/{version}/dealsheld/
,/rest/{version}/dealscompleted/{id}
, etc. Depuis, l'on a besoin de savoir quel état vous faites affaire avec dans tous les cas. Serait un régime tel que celui de sens?
Vous devez vous connecter pour publier un commentaire.
Basé sur ce que je vois ici, vous avez vraiment besoin de regarder au moins un de Jim Webber pourparlers sur le REPOS et le DDD
Ignorer l'API pour un instant - comment voulez-vous faire avec les formulaires HTML?
Vous auriez sans doute d'une page web présente une représentation de
Deal
, avec un tas de liens sur elle. Un lien vous prendrait pour leHoldDeal
formulaire, et un autre lien vous prendrait pour leChangePrice
forme, et ainsi de suite. Chacune de ces formes devraient avoir zéro, un ou plusieurs champs à remplir, et les formes de chaque post pour certaines ressources pour mettre à jour le modèle de domaine.Seraient-ils tous les post pour la même ressource? Peut-être, peut-être pas. Ils ont tous le même type de support, donc si ils étaient tous les publiant sur le web même point de terminaison, vous auriez à décoder le contenu de l'autre côté.
Compte tenu de cette approche, comment voulez-vous mettre en œuvre votre système? Eh bien, le type de média veut être json, basée sur des exemples, mais il n'est pas vraiment quelque chose de mal avec le reste.
C'est très bien.
Euh... non. Le REPOS ne se soucie pas de l'orthographe de vos identifiants de ressource. Il y a un tas d'URI meilleures pratiques qui prétendent que les verbes sont mauvais - c'est vrai - mais ce n'est pas quelque chose qui résulte de REPOS.
Mais si les gens sont si pointilleux, vous le nom du point de terminaison de la commande à la place du verbe. (c'est à dire: "hold" n'est pas un verbe, c'est un cas d'utilisation).
Honnêtement, que l'on n'est pas mal non plus. Vous ne voulez pas partager l'uri bien (à cause de la façon dont la méthode PUT est spécifié), mais l'utilisation d'un modèle où les clients peuvent spécifier un identificateur unique.
Voici la viande: vous êtes à la construction d'une api sur le dessus de HTTP et HTTP verbes. HTTP est conçu pour document de transfert. Le client vous donne un document décrivant une demande de changement de modèle de domaine, et vous appliquez le changement pour le domaine (ou pas), et le retour d'un autre document décrivant le nouvel état.
L'emprunt auprès de la CQRS vocabulaire pour un moment, que vous envoyez des commandes pour mettre à jour votre modèle de domaine.
Justification - vous de mettre une commande spécifique (une commande avec un code spécifique) dans la file d'attente de commandes, qui est l'une collection.
Ouais, c'est bien trop.
Prendre un autre regard sur RESTBucks. C'est un café protocole, mais l'ensemble de l'api est juste de passage de petits documents autour de l'avance de la machine d'état.
De la conception de votre api rest indépendamment de la couche domaine.
L'un des concepts clés de domain driven design est de couplage faible entre les différentes couches logicielles. Ainsi, lors de la conception de votre api rest, vous réfléchissez à la meilleure api rest vous pourriez avoir. Puis, c'est le rôle de la couche application pour appeler les objets du domaine pour effectuer les cas d'utilisation.
Je ne peux pas le concevoir votre api rest pour vous, parce que je ne sais pas ce que vous essayez de faire, mais voici quelques idées.
Si je comprends bien, vous avez un Deal de ressources. Comme vous l'avez dit, la création/suppression sont faciles :
Ensuite, vous voulez pour "tenir" une affaire. Je ne sais pas ce que cela signifie, vous avez à penser à ce que cela change dans la ressource "Deal". Faut-il changer un attribut? si oui, alors vous êtes tout simplement la modification de l'accord de la ressource.
METTRE /le reste/{version}/offres/{id}
- T-il quelque chose? Vous pouvez avoir plusieurs tient sur une Affaire? Me semble que "hold" est un substantif. Si c'est moche, trouver un meilleur nom.
POST /le reste/{version}/offres/{id}/contient
une autre solution: oubliez RESTE de la théorie. Si vous pensez que votre api serait plus clair, plus efficace, plus simple avec l'utilisation de verbes dans l'url, puis par tous les moyens, de le faire. Vous pouvez probablement trouver un moyen de l'éviter, mais si vous ne pouvez pas, ne pas faire quelque chose de moche juste parce que c'est la norme.
Regarder l'api twitter: beaucoup de développeurs disent que twitter a ainsi conçu une API. Tadaa, il utilise des verbes! On s'en fout, tant que c'est cool et facile à utiliser?
Je ne peux pas le concevoir votre api pour vous, vous êtes le seul qui sait votre cas d'utilisation, mais je vais le dire encore une fois mes deux conseils:
L'article Exposer CQRS Par le biais d'une API RESTful est une approche détaillée de résoudre votre problème. Vous pouvez consulter la prototype de l'API. Quelques commentaires:
J'ai séparé les cas d'utilisation (UCs) en 2 groupes: les commandes et les requêtes (CQRS), et j'ai 2 manettes (une pour les commandes et l'autre pour les requêtes). Le RESTE des ressources n'ont pas à être les objets de modèle pour effectuer des opérations CRUD sur eux comme un résultat de POST/GET/PUT/DELETE. Les ressources peuvent être n'importe quel objet que vous voulez. En effet, en DDD vous ne devriez pas vous exposer modèle de domaine pour les contrôleurs.
(1) RestApiCommandController: Une méthode par commande de cas d'utilisation. Le RESTE des ressources dans l'URI est la commande nom de la classe. La méthode est toujours la POSTE, parce que vous créez la commande, et puis vous exécutez à travers un bus de commande (un médiateur dans mon cas). Le corps de la requête est un objet JSON qui mappe les propriétés de la commande (les arguments de l'UC).
Par exemple:
http://localhost:8181/command/asignTaskCommand/
(2) RestApiQueryController: Une méthode par requête cas d'utilisation. Voici le RESTE des ressources dans l'URI est la DTO de l'objet retourné par la requête (en tant qu'élément d'une collection, ou juste un seul). La méthode est toujours d'OBTENIR, et les paramètres de la requête de communications UNIFIÉES sont params dans l'URI.
Par exemple:
http://localhost:8181/query/asignedTask/1
REMARQUE: Médiateur appartient à la DDD de la couche application. C'est l'UC limite, il recherche la commande/de requête, et d'exécuter les cas de demande de service.