带有硬逻辑的 "微服务 "的架构模式(Spring引导)。

问题描述 投票:0回答:1

我有一个微服务,它通过多次调用另一个微服务来实现一些优化函数(第二个微服务计算所谓的目标函数值,第一个微服务改变这个tagrget函数的参数)。

这就需要在Rest Controller层写一些逻辑。为了清楚一些简化的代码将表示如下

@RestController
public class OptimizerController {
   private OptimizationService service;
   private RestTemplate restTemplate;

   @GetMapping("/run_opt")
   public DailyOptResponse doOpt(){
      Data iniData = service.prepareData(null);
      Result r = restTemplate.postForObject(http://calc-service/plain_calc", iniData, Result.class);

      double dt = service.assessResult(r);

      while(dt > 0.1){
          Data newData = service.preapreData(r);
          r = restTemplate.postForObject(http://calc-service/plain_calc", newData , Result.class);
          dt = service.assessResult(r);
      }

      return service.prepareResponce(r);
   }

正如我在例子中看到的,所有的人都在努力保持休息控制器尽可能的简单,并将所有的逻辑转移到服务层。但是,如果我必须从服务层调用一些其他的微服务呢?我是应该把数据形成的逻辑保留在服务层,然后返回到控制器层,还是在服务层使用RestTemplate对象,还是其他什么?

谢谢你的帮助

java spring-boot microservices spring-restcontroller
1个回答
2
投票

这是很直接的。

整个逻辑在服务层(包括其他服务)。

简单的例子。

控制器:

@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserManager userManager;

    @Autowired
    public UserController(UserManager userManager) {
        super();
        this.userManager = userManager;
    }

    @GetMapping()
    public List<UserResource> getUsers() {
        return userManager.getUsers();
    }

    @GetMapping("/{userId}")
    public UserResource getUser(@PathVariable Integer userId) {
        return userManager.getUser(userId);
    }

    @PutMapping
    public void updateUser(@RequestBody UserResource resource) {
        userManager.updateUser(resource);
    }
}

服务:

@Service
public class UserManager {

    private static final Logger log = LoggerFactory.getLogger(UserManager.class);

    private final UserRepository userRepository;
    private final UserResourceAssembler userResourceAssembler;
    private final PictureManager pictureManager;

    @Autowired
    public UserManager(
            UserRepository userRepository,
            UserResourceAssembler userResourceAssembler,
            PictureManager pictureManager
    ) {

        super();
        this.userRepository = userRepository;
        this.userResourceAssembler = userResourceAssembler;
        this.pictureManager= pictureManager;
    }


    public UserResource getUser(Integer userId) {
        User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User with ID " + userId + " not found!"));
        return userResourceAssembler.toResource(user);
    }

    public List<UserResource> getUsers() {
        return userResourceAssembler.toResources(userRepository.findAll());
    }

    public void updateUser(UserResource resource) {
        User user = userRepository.findById(resource.getId()).orElseThrow(() -> new NotFoundException("User with ID " + resource.getId() + " not found!"));
        PictureResource pictureResource = pictureManager.savePicture(user);
        user = userResourceAssembler.fromResource(user, resource);
        user = userRepository.save(user);

        log.debug("User {} updated.", user);
    }
}

服务2:

@Service
public class PictureManager {

    private static final Logger log = LoggerFactory.getLogger(PictureManager.class);
    private final RestTemplate restTemplate;

    @Autowired
    public PictureManager(RestTemplate restTemplate) {
        super();
        this.restTemplate = restTemplate;
    }


    public PictureResource savePicture(User user) {
        //do some logic with user
        ResponseEntity<PictureResource> response = restTemplate.exchange(
            "url",
            HttpMethod.POST,
            requestEntity,
            PictureResource.class);

        return response.getBody();
    }
}

仓库:

public interface UserRepository extends JpaRepository<User, Integer> {

    User findByUsername(String username);

}
© www.soinside.com 2019 - 2024. All rights reserved.