在控制器或服务中验证?

sdf*_*fsd 1 java spring spring-mvc spring-boot

我有一种在控制器中下载消息的方法

@GetMapping(value = "/sent/{id}")
public
HttpEntity<MessageSent> getMessageSent(
        @ApiParam(value = "The message ID", required = true) @PathVariable Long id
) {
    return ResponseEntity.ok().body(messageSearchService.getMessageSent(id, authorizationService.getUserId()));
}
Run Code Online (Sandbox Code Playgroud)

但是,我忘记验证有关给定 ID 的消息是否属于用户。它在服务中也没有这样做。

@Override
public MessageSent getMessageSent(
        @Min(1) Long messageId,
        @Min(1) Long userId
) throws ResourceNotFoundException {
    Optional<UserEntity> user = this.userRepository.findByIdAndEnabledTrue(userId);
    user.orElseThrow(() -> new ResourceNotFoundException("No user found with id " + userId));

    return this.messageRepository.findByIdAndSenderAndIsVisibleForSenderTrue(messageId, user.get())
            .map(MessageEntity::getSentDTO)
            .orElseThrow(() -> new ResourceNotFoundException("No message found with id " + messageId));
}
Run Code Online (Sandbox Code Playgroud)

现在我的问题是应该在控制器还是服务中完成?我更喜欢在服务中这样做,但我不知道是否合适。

dav*_*ave 7

作为一般经验法则,我会说这种业务逻辑应该在服务中。控制器应该是轻量级的并传递请求。此外,您的服务可能还有其他客户端,而不仅仅是控制器,因此这允许您将验证保存在一个地方。


Ami*_*_Af 6

  1. 不要将此验证放在控制器中 - 控制器部分只是传入请求和公开 API 的入口点。

  2. 我建议您创建额外的服务,负责进行验证并将此服务注入您的 messageSearchService 服务中。这样您就可以在其他需要相同验证的服务中使用验证服务。另外,这就是为什么你遵循每个类只有一个自己的责任的原则。