Spring rest端点和服务层分离

时间:2018-04-19 17:54:09

标签: spring rest

在Spring启动应用程序中,我有两个服务:GroupService和UserService。还有各自的模型类,Group和User以及存储库。我暴露了两个Rest端点,一个用于用户,一个用于组。现在,我有一个端点,将给定用户添加到如下所示的给定组中,暂时忘记可能的空检查和其他问题。

@PostMapping(path="groups/{group-id}/add/{user-id}")
public ResponseEntity<Group> setUserGroup(@PathVariable(value="group-id")Long groupId, @PathVariable(value="user-id")Long userId)
    {   Group group=groupService.findById(groupId);
        group.addUser(userService.findById(userId));
        return new ResponseEntity<Group>(groupService.save(group),HttpStatus.OK);
    }

现在,问题是,处理这种情况的最佳做法是什么。通过在其上注入用户服务而不是在休息端点处理它来处理组服务中的逻辑是不是很好?在这种情况下,组服务将依赖于用户服务,但是如果(让我们想象这样的情况)多个休息端点需要它,则至少可以重用逻辑。

当前的实现具有优势,因为服务不会彼此依赖。但是,如果我们有复杂的逻辑,并且假设我们有复杂的事务,那么肯定休息端点不是处理它的正确位置。请帮助我了解我应该使用哪种方法,以及什么是行业最佳实践。

1 个答案:

答案 0 :(得分:4)

看来我们这里有典型的3层架构!

  • 端点的正确位置是Controller。
  • 将用户添加到组的业务逻辑应位于服务层。 您可以自由地创建服务并在另一个内部注入服务,但避免循环依赖。还应将DAO注入服务中。
  • 应在服务层实施事务管理。 (参见Spring的@Transactional注释)
  • 如果你的课程是&#34; GroupService&#34;和&#34; UserServise&#34;包含直接存储操作的方法(例如,通过/ etc创建/读取/更新/删除/查找),它们在逻辑上不应属于服务层。这些类属于持久层,应该像GroupRepository或GroupDao(DAO - 数据访问对象)一样命名。

  • 存储库可以手动实现,但流行的方式是使用Spring Data接口。我强烈建议您查看http://projects.spring.io/spring-data/#quick-start

在您的情况下,我看到以下图片:

@Component
GroupRepository {
   // Manually implemented DAO, but more simple way is Spring Data
   ...
}

@Component
UserRepository {
   // Manually implemented DAO
   ...
}

@Service
ManagementService {
  @Autowire
  private UserRepositoty userRepository;

  @Autowire
  private GroupRepository groupRepository;

  @Transactional
  public Group addUserToGroup (Long groupId, Long userId) {
         Group group=groupRepository.findById(groupId); group.addUser(userRepository.findById(userId));
          return groupRepository.save(group);
    }
}

@Controller
ManagementController {

      @Autowire
      private ManagementService managementService;

      @PostMapping(...)  
      public ResponseEntity<Group> setUserGroup(@PathVariable Long groupId, @PathVariable Long userId) { 

          return new ResponseEntity<Group>(managementService.addUserToGroup(groupId, userId),HttpStatus.OK);
      }
}

请参阅 https://www.petrikainulainen.net/software-development/design/understanding-spring-web-application-architecture-the-classic-way/

P.S。一句话是关于ResponseEntity的用法:在大多数情况下,它不是强制性的,下面是简化的代码。 Magic是RestController注释的幕后推手。 https://spring.io/guides/gs/rest-service/

@RestController
ManagementController {

      @Autowire
      private ManagementService managementService;

      @PostMapping(...)  
      public Group setUserGroup(@PathVariable Long groupId, @PathVariable Long userId) { 

          return managementService.addUserToGroup(groupId, userId);
      }
}