具有硬逻辑(Spring 引导)的 "microservice" 的架构模式
Architecture pattern for "microservice" with hard logic (Spring boot)
我有一个微服务,它通过多次调用另一个微服务来实现一些优化功能(第二个微服务计算所谓的目标函数值,第一个微服务更改此 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);
}
正如我在示例中看到的那样,所有人都在努力使 rest 控制器尽可能简单,并将所有逻辑移至服务层。但是,如果我必须从服务层调用其他一些微服务怎么办?我应该在服务层中保留数据格式的逻辑,return 将其保留到控制器层,在服务层中使用 RestTemplate 对象还是其他?
感谢您的帮助
很简单。
整个逻辑在服务层(包括其他服务)。
简单示例:
控制器:
@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);
}
我有一个微服务,它通过多次调用另一个微服务来实现一些优化功能(第二个微服务计算所谓的目标函数值,第一个微服务更改此 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);
}
正如我在示例中看到的那样,所有人都在努力使 rest 控制器尽可能简单,并将所有逻辑移至服务层。但是,如果我必须从服务层调用其他一些微服务怎么办?我应该在服务层中保留数据格式的逻辑,return 将其保留到控制器层,在服务层中使用 RestTemplate 对象还是其他?
感谢您的帮助
很简单。
整个逻辑在服务层(包括其他服务)。
简单示例:
控制器:
@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);
}