Let's take some classic enterprise example: Order
and OrderItem
public class Order
{
public Guid Id { get; set; }
public ICollection<OrderItem> Items { get; set; }
}
public class OrderItem
{
public Guid Id { get; set; }
//...
}
Now, what's the most reasonable way to update the order's items using PUT
or PATCH
(JSON Patch) ?
Should I PUT api/orders/{id}
with a new collection (with removed, added or updated items) or handle it differently someway? Like instead of returning a serialized collection of items, return list or links for each item like: api/orders/{id}/items/{id}
. So it would be more HATEOAS like and REST like...
public class Order
{
public Guid Id { get; set; }
public ICollection<Link> Items { get; set; }
}
Then if I wanted to update or remove some item from the order I would use those links, but the downside of this is that client-side implementation will not be that straightforward.
The other solution I can think of is returning ids of items like:
public class Order
{
public Guid Id { get; set; }
public ICollection<Guid> Items { get; set; }
}
but it doesn't look too nice for me, so what is more or less industry standard for dealing with this?
- Returning embedded items
- Returning item URLs
- Returning item ids
1 Answer 1
If Order has the OrderItems attached then you should just update Order and not provide api methods for OrderItems.
so
public class Order
{
public Guid Id { get; set; }
public ICollection<OrderItem> Items { get; set; }
}
api/orders/UpdateOrder {"Id" : "guid" "Items" : [{...},{...}] }
api/orders/GetOrderById
If OrderItem just has an OrderId and Order doesn't contain a list of them, then you should have api methods for OrderItems
so.
public class Order
{
public Guid Id { get; set; }
}
public class OrderItem
{
public Guid Id { get; set; }
public Guid OrderId { get; set; }
}
api/orders/UpdateOrder {"Id" : "guid"}
api/orders/GetOrderById
api/orders/UpdateOrderItem {...}
api/orders/GetOrderItemsByOrderId
api/orders/DeleteOrderItem
*avoiding HTTP verbs for clarity
At first glance the complex object/aggregate/first approach seems far superior. But as you object starts getting larger, and you are only needing some of the child objects for certain operations, the second approach can become more efficient.
For example, you can imagine that I might want to know and do lots of things about/with a Company object without loading the List of all its Employees past and present every time.
-
2An order cannot exist without the items.Konrad– Konrad2018年09月06日 09:09:33 +00:00Commented Sep 6, 2018 at 9:09
-
1hmm I would never recommend HATEOAS, let me edit and add more detail, see if you still think its wiseEwan– Ewan2018年09月06日 11:00:22 +00:00Commented Sep 6, 2018 at 11:00
-
1@Konrad what happens if i remove all the items from an order? or create an order but haven't added any items yet?Ewan– Ewan2018年09月06日 11:06:42 +00:00Commented Sep 6, 2018 at 11:06
-
1@konrad its a bit off topic. basically no client can be clever enough to understand HATEOAS.Ewan– Ewan2018年09月06日 12:24:44 +00:00Commented Sep 6, 2018 at 12:24
-
1Additionally, when you send back the resource to the server, you don't send the HATEOAS representation you got with GET. You may send a total different representation. For instance, you will never send back the "links" or "relations" since it's the server's responsibility to decide the links it wants you to discover and navigate through.Laiv– Laiv2018年09月06日 12:58:29 +00:00Commented Sep 6, 2018 at 12:58
Explore related questions
See similar questions with these tags.