As the title suggests what is the best practice when designing service layers?. I do understand service layer should always return a DTO so that domain (entity) objects are pres
I'm from C#
background but the concept remains same here.
In a situation like this, where we have to pass the parameters/state from application layer to service layer and, then return result from service layer, I would tend to follow separation-of-concerns. The service layer does not need to know about the Request
parameter of you application layer/ controller. Similarly, what you return from service layer should not be coupled with what you return from your controller. These are different layers, different requirements, separate concerns. We should avoid tight coupling.
For the above example, I would do something like this:
class Controller
{
@Autowired
private ItemService service;
public ItemResponse createItem(CreateItemRequest request)
{
var creatItemDto = GetDTo(request);
var itemDto = service.createItem(createItemDto);
return GetItemResponse(itemDto);
}
}
This may feel like more work since now you need to write addional code to convert the different objects. However, this gives you a great flexiblity and makes the code much easier to maintain. For example: CreateItemDto
may have additional/ computational fields as compared to CreateItemRequest
. In such cases, you do not need to expose those fields in your Request
object. You only expose your Data Contract
to the client and nothing more. Similarly, you only return the relevant fields to the client as against what you return from service layer.
If you want to avoid manual mapping between Dto
and Request
objects
C# has libaries like AutoMapper
. In java world, I'm sure there should be an equivalent. May be ModelMapper can help.