Best practice for transferring data to the service layer
I am working on a web application in spring following the MVC pattern and was wondering what is considered the "best practice" for creating a robust service layer. The reason for this question is the following situation:
The page for editing user information is loaded. After submitting this form, I collect all my data in my controller method in a specific Command class containing only the data needed for the subsequent action (user update).
Now I can think of several situations to pass this information to my service layer:
- Passing the command itself: userService.save (command);
- Passing the model class selected in the controller: userService.save (user);
- Passing both the model class and the command: userService.save (user, command);
- Passing all parameters individually: userService.save (command.getName (), ...)
In my opinion, passing the command class itself looks like the most elegant solution, since I can first fully validate all the values with the framework and then pass them to my service. I'm worried that when I call a method from another class (not through my form / controller), I might populate that command object with invalid data, leading to possible errors in the service level.
What would you recommend and why?
source to share
Seeing that I have the following ideas Passing the command itself: userService.save (command);
This may not be a good idea as your service level is unreasonable depending on the Command object
Passing a model class, fetched in the controller: userService.save(user);
I will vote for this. Service level is just what he really should have known
Passing both a model class and the command: userService.save(user, command);
Not. Same as the first option
Passing all of the parameters individually: userService.save(command.getName(), ...)
Hmmmm ... not sure ... Perhaps in the future this will be the main task.
I think if you want to do the validation, Use validation util classes to do the validation
which can be used for both Service and UI layer. Here a lot validation can be centralized.
source to share
Any option using the Command object will cause problems. It breaks the clutch. Now your service level is closely related to the service level. Please don't do this.
(EDIT: In my answer below, when I say Model for the View Layer I'm talking about the View Model, and for the Service Layer it's the Domain Model) Sending a Model Object looks like a good option. But that depends on how the model was created. In some cases the presentation layer will need a different model structure and the service layer will need a moderatley / completely different structure.
If both levels have different needs, you need to create 2 models. Thus, the structure of the service layer structure should not change when the presentation layer changes. This is important because a service can have multiple consumers and it might not change when the presentation layer changes.
If they don't have a different structure, I would still create them in terms of the service layer, since the service is a real reusable component here.
source to share
A good template for working with commands in multi-tier systems is to have a CommandBus service that routes your commands to their specific handlers. This way you disconnect your controller from its services (when it connects to the common routing system).
commandBus.handle(command);
You have to do the extra work of configuring the command bus handlers, but it will pay off in the long run when you can reuse this routing information:
commandBus.register(commandType, handlerService);
and then you should be able to postpone command checking in the service commandBus
(although that would mean some confusion of problems for commandBus)
commandBus.registerValidator(commandType, validatorsCollection);
source to share