Reputation: 40038
Today i have a big discussion with one of our team member about validation of RESTful API input in Controller
and Service
layer and i feel it is a bad day for making bigger argument. So we have a spring boot microservice application with layered architecture
Controller --> Service --> Repository
The argument is having the validation at each layer or just having the validation at Controller
layer, for example we have Controller
with POST
request and using JSR-380 validation for input request body
Controller :
@PostMapping(value = "/", consumes = {"application/json"}, produces = {"application/json"})
public ResponseEntity<Detail> createConfig(
@NotNull(message = "{error.message.config_detail}")
@RequestBody @Validated Config config) {
return new ResponseEntity<>(configService.create(config.getConfigId(), config.getTaskId()), HttpStatus.CREATED);
}
Config : Request Body
public class Config {
@ApiModelProperty(name = "config_id", example = "1", required = true)
@NotNull(message = "{error.message.config_id}")
private Long configId;
@ApiModelProperty(name = "task_id", example = "11", required = true)
@NotNull(message = "{error.message.task_id}")
@Min(value = 0, message = "{error.message.task_id}")
@Max(value = 9999, message = "{error.message.task_id}")
private Integer taskId;
// bunch of addition fields with validations
}
If the validation success then calling the Service
method with some properties from Config
Service :
public Detail create(@Valid @NotNull Long configId, @NotNull Integer taskId) {
// some business logic to convert to entity and saving to database
return repository.save(entity));
}
So if we see the above code, same validation is done at Controller
and Service
, So i argued that there is no need of validating in Service
layer, perform the validation at controller layer and if input is wrong then throw 400
or 500
to user. But another person in team also suggest having validation in each block for whatever is used in the block, so that individual piece of code is safe (focusing on the unit instead of the integration path).
I know i might be wrong in this case, but still not able to understand the validation at each layer,(null check i agree) so it is recommended approach having validation at each level
Controller --> validation call service
Service ---> validation and call business
Business ---> validation and call repository
Repository --> save
But what is the prefered way of validation ? according to me if Controller
input is valid call Service
and perform business logic and call Repository
. correct me if i'm wrong so that i can follow the recommended pattern
Upvotes: 4
Views: 1336
Reputation: 4368
Unless you are using the services and / or repositories as libraries in other projects, too, it does not make sense to do the validation multiple times. If the controllers are the only classes accessing the additional layers there is no need for additional validation as you and your controller are the only one to access the Spring beans. You and the controller are in control of accessing the services with valid parameters.
Doing several validations has the disadvantage of writing more complex services - including unit tests. It is slower. Changing the validation will take longer as multiple layers have to be changed - including unit tests. The validations on several layers can and will differ in a matter of time.
The preferred way is to do the validation once in (or even before) the controller and writing integration tests to ensure its functionality.
Upvotes: 1
Reputation: 2601
It is situational. Some validation needs to be performed in the service layer. Say, you will need to change a state of an object, but only if certain conditions are met etc. A part from that, as a rule of thumb i follow these guidelines: If your services are publicly exposed to other services via RMI, then service layer validation is mandatory, if not go with controller level validation.
Upvotes: 1
Reputation: 152
You are right : the validation should be placed in controller, if possible. And it's make no sense in my opinion to validate the data more then 1 time. See also DRY principle https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
Upvotes: 1