I've been struggling with this issue for a while. Let's say you have a business application that has a rich domain and in one of the front-end views you show a list of open
Orders. In this view you show things like that orderDate, customerName, totalAmount,... but the client also wants to see how many items are in the order (basically the count of OrderItems entity). What is the best way to handle this?
Orderclass has a
List<OrderItem>which is fetched lazily
- Each ResponseDTO object only contains its core properties and any properties from
Customerwould be included when fetching an
You can do a rest call for the
Order resource by calling
/api/orders, you'll get a response with the core properties and the customer data. For each order you'll have to do a new fetch to
/api/orders/<id>/items. This is basically an N+1 problem with many HTTP calls.
I change my initial assumption and eagerly fetch collections and immediately include the
OrderItems in the ResponseDTO. The question then becomes, am I going to eagerly fetch each collection of each entity? This seems like a serious performance issue. In this solution the front end would only need to make 1 call.
Initial assumptions are in play, so I lazily fetch collections but I move the N+1 problem from the front-end to the back-end (so no extra HTTP calls), not really a solution but at least the expensive HTTP calls are weeded out.
In my rich domain model I add an attribute to the
Order entity called
numberOfItems. Whenever the method
addOrderItem(OrderItem item) is invoked on an
Order object, I increment the
numberOfItems attribute. It is stored in the database as well. This way I can have all my initial assumptions and use the ResponseDTO with only core properties and I only make 1 HTTP call. The issue I have with this solution is that many people say that you shouldn't store aggregate data like that in the database.
I realize there's no perfect solution and it always depends, but for the life of me I can't seem to find good discussions about this issue. When you google an issue like this you often find information about HATEOAS but that would fit in my Solution 1, which I don't think is really a solution.
If anyone can give an alternative solution or improve on any of the solutions I gave, it would be greatly appreciated.