'How to design REST API for aggregate with nested objects?
I'm designing my first REST-API and am struggling to design the API for a Cart aggregate that has nested objects:
Cart 1->n SubCart 1->n CartItem.
The Cart aggregate is saved as a whole. Each time an item is placed in the Cart various discounts have to be calculated that depend on the other CartItems even from other SubCarts. Therefore the client app needs to receive a full Cart aggregate with all nested objects.
Evens says in his DDD book that "... The root is the only member of the AGGREGATE that outside objects are allowed to hold references to...".
I understand the general idea, but it is not clear what reference means. Some articles speak about in memory object references, others speak about id references, too. If the user i.e. wants to increase the quantity of an CartItem the UI must have a way to identify the item in the cart. It needs to have some ID/reference. Otherwise how shall the Cart know what item's quantity should be increased. What did Evans mean with reference? The way it is worded is very confusing.
Since all commands go through the Cart aggregate in the backend I wonder if this also should be applied to the REST API. Since I lack the experience I don't know what issues or side effects one or the other solution will have (i.e. caching, security)? Why would one prefer one or the other?
For example for updating the quantity of a CartItem I see the following options:
PATCH carts/{id}/subcarts/{subcart_id}/cartitems/{cartitem_id}.PATCH carts/{id}/{subcart_id}/{cartitem_id}.PATCH /carts/{id}?subcart={subcart_id}&cartitem={cartitem_id}.PATCH carts/{id}havingsubcart_idandcartitem_idin the body.
I saw that GIT API used the shorter form of option 2 in some cases. When should one chose option 1 over option 2?
For options 3 and 4 it would be natural to return the new Cart object with possible discounts as a result of the PATCH.
With option 1 and 2 it seems not RESTful to return a Cart object after a PATCH of a CartItem. The return could be a 204 and the client must then send a GET on the Cart again, resulting in two calls.
Thanks for any help and insights.
Solution 1:[1]
My suggestion is to keep it as simple and understandable as you can.
First of all, REST guidelines are conventions, not rules written in stone. Also, you say you are afraid not to be RESTful. I'm almost sure you will not be so anyway :-). For example, I'm almost sure you are not going to implement HATEOAS at all, and without it you are not creating a RESTful system (like the vast majority of the so-called REST APIs you find around, after all :-))
That said, you should think in terms of resources and CRUD operations you want to perform on them. Since discounts depend on the presence of other items in subcarts, my suggestion is to consider the cart as your resource, including its subcarts and items. This simplifies your work and the overall understanding of the system.
Make your decision based on performance and clarity issues.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Andrea Chiarelli |
