0

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
2

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.

17
  • 2
    An order cannot exist without the items. – Konrad Sep 6 '18 at 9:09
  • 1
    hmm I would never recommend HATEOAS, let me edit and add more detail, see if you still think its wise – Ewan Sep 6 '18 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 Sep 6 '18 at 11:06
  • 1
    @konrad its a bit off topic. basically no client can be clever enough to understand HATEOAS. – Ewan Sep 6 '18 at 12:24
  • 1
    Additionally, 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 Sep 6 '18 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.