Reputation: 6650
I am quite confused with usage of @Controller
, @Service
and @Repository
in Spring-MVC.
I have couple of questions and would be grateful to have them answered.
I know controller is used to receive requests from view and make requests to for views to show results to users. My question is that to what extend can I do processing in a class with controller annotation? Should I do all the processing in service annotated class and keep controller for receiving requests and returning responses ONLY? I would like to know whats the best practice?
Lets say I need to call different methods of service annotated class to process the results should I call them all from controller or pass them to service annotated class? (This is just an example)
If I would not want to process the results and just willing to send requests to database and receive the results, do I still need to have a service annotated class in between controller and repository?
Lets say I receive a product id and would like to retrieve and show details of the product.(This is just an example)
Upvotes: 13
Views: 27867
Reputation: 40076
I think it is hardly any "best approach" but approach that suit your need. Here is the approach I used in my past projects, which kind of base on Domain Driven design.
Presentation Layer : Controller (@Controller)
Merely responsible to presenting a business function (provided in Application Service Layer). Hence mostly delegation to App Service, doing data massaging and presentation-related logic.
Application Service Layer : Application Service (@Service)
High level speaking, it represents business use cases. Hence transaction boundary is set on the methods (as each method is a use-case, hence a unit of work). As I am against use of anemic model, real business logic should be in the domain model layer. This layer mostly make use of domain layer to compose of a meaningful use case. Mostly data transformations (depending on your design), and delegations to domain layer artifacts.
Domain Layer : Model, Domain Service (@Service), Repository (@Repository) etc
Business logic are in domain models, or Domain Services. Repository are the artifacts to retrieve domain models.
Infrastructure Layer
Infrastructure-dependent implementation of some domain artifacts.
Go back to your question:
There is no right or wrong. If you are making a totally self-contained simple application, there may be no benefit of splitting the role of Controller and Application Service layer. Also, for people that are so get used to anemic model development, you may need a Service just to put your business logic in. So, you need to ask yourself, what is your purpose to have certain layer in your design, and is it something that is really meaningful to you. For my approach, I think it is already quite clear on what to do for which layer. You may take it as reference if you want.
Similar answer: If you are doing the role of Presentation + Application Service in your Controller, there is no special reason of making up another Service. But if you want to maintain a presentation-neutral application service layer, then you should provide those "CRUD" actions through your app service.
Upvotes: 9
Reputation: 4692
Converting comments into answer.
Upvotes: 1
Reputation: 2933
Well depends on requirements, I think you would be better off to keep controllers clean, they are used for presentation so you should only keep whatever is related to presentation layer there, nevertheless, if you need to pass the inputs to a service class and from there call other service methods, I would say do not bother creating a new method in service class just call the service methods directly.
Lets say these methods are in service class, I think it wont make sense to send the input to a service class, and have following code in there. I would suggest to keep this code in controller and call the methods as following:
if(input is valid){
result1 = serviceClass.dothisstuff(input);
result2 = serviceClass.thenthisstuff(result1);
}else{
result1 = serviceClass.dothosestuff(input);
result2 = serviceClass.thenthosestuff(result1);
}
I would say use all three layers all the time for the sake of future requirements.
Upvotes: 3