Reputation: 5399
I'm participating in implementing rest API application and we're sticking to Spring Boot as a framework.
We're at the very beginning of implementing the system but even at this stage of the project, it starts to feel like it is something wrong with application design.
We have 3 layers in our application:
My concern about application design described above:
It will really help to see some type of guidelines, best practices or projects which shows how to organize communications between application layers in this type of application.
Thanks a lot!
Additions below
Some code snippets:
class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private UserService userService;
public OrderResultDto createOrder(OrderRequestDto dto) {
return orderService.makeOrderRequest(userService.getAuthenticatedUser(), dto)
}
}
class OrderService {
@Autowired
private OrderRepository orderRepo;
public makeOrderRequest(User user, OrderRequestDto dto) {
// do some complex business logic
}
}
It seems not ok to assign dto we send to frontend as JSON to Service contract... Moreover, if we need to call this service from another method, that method will be bound to this dto as well which is not good.
Upvotes: 1
Views: 2346
Reputation: 9586
The controller layer is the web facing layer. Its job is to accept input and generally speaking, convert it into a format for use with the service layer and call the service. As you say, Spring does this conversion out of the box, E.G. modeling JSON into a DTO based on the type of controller method parameter.
convert dto and logged in user information to some object or db entity (!) to make a call of the Service layer. return result to client as dto object which is converted from some object or db entity (!)
This is poor separation of abstractions. How would you manage transactions, for instance? It's also dangerous exposing a "live" JPA entity to the web layer. Furthermore, the web is just one way you may want to interact with your services. What would happen if you want to run your service as a scheduled job using, E.G. Quartz? The conversion from JPA entity to DTO and back should be done in the service layer, as should transaction management.
return result of the business logic as some object or db entity object (!) Again, the service should be mapping entities to DTOs. There should be no objects leaking from the repository out of the service.
The controller can do the automatic conversation to the DTO and that can be the input/output to/from the service. E.G. controller accepts a PersonDTO, Spring performs the mapping to the DTO with jsr-303 bean validation, the service is called with the PersonDTO, maps the DTO to an entity, calls the repository layer, maps the returned entity to a DTO then returns the DTO.
From your question, it sounds like you're very much thinking along the right lines. The only thing I'd question is the need for controller DTOs and service DTOs. Using the same class for this is fine.
Upvotes: 1