【发布时间】:2020-11-28 22:05:51
【问题描述】:
我有一个带有数据库的小型 Spring Boot 服务(我使用 Spring Data JPA),我需要来自另一个 REST API 的一些额外信息。所以我只能通过从我的数据库中调用带有 ids 的 rest API 来获取这些附加信息,然后保存它。
所以我创建了一个带有端点/migrate 的控制器,我的想法是,当我启动服务时,我可以调用这个端点,然后我使用findAll() 加载所有条目,最后我遍历它们并调用每个人的第 3 方休息端点以获取附加信息。到目前为止,直觉......但我不确定这里最好的方法是什么。我的端点应该只是一个void 方法,还是应该建模它ResponseEntity?我的问题或多或少是这里的最佳做法。
这是一些代码。
@RestController
@RequiredArgsConstructor
@Slf4j
public class MigrationController {
private final MigrationService migrationService;
@GetMapping("/migrate")
public ResponseEntity<MigrationResult> migrateData() {
var migrationResult = migrationService.migrateData();
// this is not optimal here...
if (migrationResult.getStatusCode().startsWith("2")) {
return ResponseEntity.ok().body(migrationResult);
} else {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(migrationResult);
}
}
}
这里是MigrationService:
@Service
@AllArgsConstructor
public class MigrationService {
private final CustomerRepository customerRepository;
private final OrderService orderService;
public MigrationResult migrateData() {
var updatedCustomersCounter = new AtomicInteger();
var migrationResult = new MigrationResult();
long start = System.currentTimeMillis();
var customers = customerRepository.findAll();
if (customers.isEmpty()) {
return MigrationResult.builder()
.message("No customer datafound in database")
.statusCode("404")
.build();
}
for (Customer customer : customers) {
try {
var order = orderService.getOrderById(customer.getOrderId());
if (order != null && !order.getOrders().isEmpty()) {
customer.setUniqueId(order.getOrders().get(0).getUniqueId());
updatedCustomersCounter.getAndIncrement();
customerRepository.save(customer);
}
if (order != null && order.getOrders().isEmpty()) {
return MigrationResult.builder()
.message("Migration of unique Id for oder id " + order.getOrderId() + " failed.")
.statusCode("500")
.build();
}
} catch (Exception e) {
migrationResult.setMessage("Unexpected error while updating customer.");
migrationResult.setStatusCode("500");
}
migrationResult.setMessage(
"Migration of " + updatedCustomersCounter.get() + " customers finished in: " + (System.currentTimeMillis() - start)
+ "ms. Total number of entries with present orderId " + filteredDataPlans.size());
migrationResult.setStatusCode("200");
}
return migrationResult;
}
}
这是我与 ResponseEntity 一起使用的模型:
public class MigrationResult {
@NotNull
private String statusCode;
@NotNull
private String message;
}
如您所见,我需要来自所谓的 orderService 的 uniqueId,然后将其保存到我的客户实体中。显然这需要一些时间才能完成(大约 1000 个条目 -> 调用)。
我觉得我这样做的方式很“可疑”。但我不确定什么是最好的方法,即做这样的事情的更好方法是什么,并且在错误消息和可能的超时(如果作业运行时间过长)方面仍然符合 HTTP。此外,没有 UI - 这就是为什么我决定使用这个小的 POJO MigrationResult 来处理我可以变成 JSON 的消息。
【问题讨论】:
标签: java spring-boot api rest spring-data-jpa