8.2.4 使用 Spring WebFlux 暴露 REST API
在 Spring WebFlux 应用程序中定义 RESTful 端点有两种选择:@RestController 类或函数式 bean(路由函数)。对于 Order Service 应用程序,我们将使用第一种选择。与我们在第 3 章中所做的不同,方法处理程序将返回响应式对象。
对于 GET 端点,我们可以使用前面定义的 Order 域实体并返回 Flux
创建一个新的 com.polarbookshop.orderservice.order.web 包,并定义一个 OrderRequest 记录来保存提交的订单信息。
代码清单 8.14 带验证约束的 OrderRequest DTO 类
package com.polarbookshop.orderservice.order.web;
import javax.validation.constraints.*;
public record OrderRequest(
@NotBlank(message = "The book ISBN must be defined.") // 不能为 null 且必须包含至少一个非空白字符
String isbn,
@NotNull(message = "The book quantity must be defined.") // 不能为 null
@Min(value = 1, message = "You must order at least 1 item.") // 必须包含 1 到 5 的值
@Max(value = 5, message = "You cannot order more than 5 items.")
Integer quantity
) {}
在同一个包中,创建一个 OrderController 类来定义 Order Service 应用程序暴露的两个 RESTful 端点。由于你为 OrderRequest 对象定义了验证约束,你还需要使用熟悉的 @Valid 注解在调用方法时触发验证。
代码清单 8.15 定义处理 REST 请求的处理程序
package com.polarbookshop.orderservice.order.web;
import javax.validation.Valid;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import com.polarbookshop.orderservice.order.domain.Order;
import com.polarbookshop.orderservice.order.domain.OrderService;
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderService orderService;
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@GetMapping
public Flux<Order> getAllOrders() {
return orderService.getAllOrders();
}
@PostMapping
public Mono<Order> submitOrder(@RequestBody @Valid OrderRequest orderRequest) {
return orderService.submitOrder(orderRequest.isbn(), orderRequest.quantity());
}
}
现在 Order Service 有了一个基本的 API。虽然它目前只返回被拒绝的订单,但你可以启动它并测试端点是否工作。在下一节中,你将学习如何使用 Spring WebClient 实现一个响应式客户端,以与 Catalog Service 交互并真正处理订单。