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 preserved within the service layer. But what should be the input for the service layer from the controllers?
I put forward three of my own suggestions below:
Method 1: In this method the domain object (Item) is preserved within the service layer.
class Controller
{
    @Autowired
    private ItemService service;
    public ItemDTO createItem(IntemDTO dto)
    {
        // service layer returns a DTO object and accepts a DTO object
        return service.createItem(dto);
    }
}
Method 2: This is where the service layer receives a custom request object. I have seen this pattern extensively in AWS Java SDK and also Google Cloud Java API
class Controller
{
    @Autowired
    private ItemService service;
    public ItemDTO createItem(CreateItemRequest request)
    {
        // service layer returns a DTO object and accepts a custom request object
        return service.createItem(request);
    }
}
Method 3: Service layer accepts a DTO and returns a domain object. I am not a fan of this method. But its been used extensively used at my workplace.
class Controller
{
    @Autowired
    private ItemService service;
    public ItemDTO createItem(CreateItemRequest request)
    {
        // service layer returns a DTO object and accepts a DTO object
        Item item = service.createItem(request);
        return ItemDTO.fromEntity(item);
    }
}
If all 3 of the above methods are incorrect or not the best way to do it, please advise me on the best practice.
 
     
    