Java 分层体系结构中的Spring boot restful API验证
今天,我与我们的一位团队成员就如何验证Java 分层体系结构中的Spring boot restful API验证,java,spring,spring-boot,validation,Java,Spring,Spring Boot,Validation,今天,我与我们的一位团队成员就如何验证Controller和Service层中的RESTful API输入进行了一次大讨论,我觉得今天不适合进行更大的争论。因此,我们有一个具有分层架构的spring boot微服务应用程序 Controller --> Service --> Repository 参数是在每一层进行验证,或者只是在控制器层进行验证,例如,我们有控制器和POST请求,并对输入请求体使用验证 控制器: @PostMapping(value = "/", consume
Controller
和Service
层中的RESTful API输入进行了一次大讨论,我觉得今天不适合进行更大的争论。因此,我们有一个具有分层架构的spring boot微服务应用程序
Controller --> Service --> Repository
参数是在每一层进行验证,或者只是在控制器
层进行验证,例如,我们有控制器
和POST
请求,并对输入请求体使用验证
控制器:
@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);
}
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));
}
如果验证成功,则从Config
调用带有某些属性的Service
方法
服务:
@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);
}
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));
}
因此,如果我们看到上面的代码,同样的验证在控制器
和服务
上进行,因此我认为没有必要在服务
层进行验证,在控制器层执行验证,如果输入错误,则将400
或500
扔给用户但团队中的另一个人也建议在每个块中对块中使用的任何东西进行验证,以便单个代码段是安全的(关注单元而不是集成路径)。
我知道在这种情况下我可能是错的,但仍然无法理解每一层的验证(我同意空检查),因此建议在每一层进行验证
Controller --> validation call service
Service ---> validation and call business
Business ---> validation and call repository
Repository --> save
但首选的验证方式是什么?根据我的判断,如果
控制器
输入有效,则调用服务
,执行业务逻辑并调用存储库
。如果我错了,请纠正我,这样我就可以按照建议的模式进行验证。你是对的:如果可能,验证应该放在控制器中。在我看来,验证数据超过1次是没有意义的。
另请参见干燥原理,它是情境性的。需要在服务层执行一些验证。比方说,您将需要更改对象的状态,但前提是满足某些条件等。 其中一部分,作为经验法则,我遵循以下准则:
如果您的服务通过RMI公开给其他服务,则服务层验证是强制性的,如果不进行控制器级验证。除非您在其他项目中将服务和/或存储库用作库,否则多次进行验证是没有意义的。 如果控制器是访问附加层的唯一类,则无需进行额外的验证,因为只有您和您的控制器访问SpringBean。您和控制器控制着使用有效参数访问服务 进行多次验证的缺点是编写更复杂的服务,包括单元测试。 它比较慢。 更改验证将花费更长的时间,因为必须更改多个层,包括单元测试。 几层上的验证在时间上可能会有所不同
首选的方法是在控制器中(甚至之前)进行一次验证,并编写集成测试以确保其功能。如果数据无效,为什么需要调用服务并在那里进行验证?