您将如何使用 Spring Boot 处理仅具有可选查询参数的 REST API?
Posted
技术标签:
【中文标题】您将如何使用 Spring Boot 处理仅具有可选查询参数的 REST API?【英文标题】:How would you handle a REST API with only optional query params with Spring Boot? 【发布时间】:2020-06-04 23:58:40 【问题描述】:我想构建一个返回 Order
对象的简单端点,我可以在其中通过单个查询参数或多个查询参数的组合搜索此订单。所有这些查询参数都是可选的,原因是不同的人会根据不同的 Id 访问这些订单。
例如:
/order/items?itemId=itemId&orderId=orderId&deliveryId=deliveryId&packetId=packetId
@GetMapping(path = "/order/items", produces = "application/json")
public Order getOrders(@RequestParam Optional<String> itemId,
@RequestParam Optional<String> orderId,
@RequestParam Optional<String> deliveryId,
@RequestParam Optional<String> packetId)
当然,我也可以跳过 Java Optional 并使用 @RequestParam(required = false)
,但这里的问题是如何避免检查查询参数是否为空的 if-else
或 .isPresent()
噩梦?或者是否有一种优雅的方式,取决于参数的星座,进一步传递给我的服务和 Spring Data JPA 存储库。
【问题讨论】:
我总是像WHERE (:myParam IS NULL OR TABLE.COLUMN = :myParam )
这样为可选参数构建我的 SQL...这样您的查询处理 null 并且您可以从该查询中获得更多信息..所以我实际上会使用@RequestParam(required = false)
但是搜索端点应该真正返回一个数组,而不是单个项目
将空值传递给查询和let the query handle it。
好吧,在这种情况下,如果存在的话,它应该只是一个订单。
如果它是一个搜索端点(它是),它应该返回一个结果数组......它也被称为getOrders
,它也会让人们相信它返回多个......跨度>
【参考方案1】:
为了尽量减少方法中的参数数量,您可以将查询参数定义为类的字段:
@Data
public class SearchOrderCriteria
private String itemId;
private String orderId;
private String deliveryId;
private String packetId;
然后在您的控制器方法中接收此类的实例:
@GetMapping(path = "/order/items", produces = "application/json")
public ResponseEntity<OrderInfo> getOrder(SearchOrderCriteria searchCriteria)
OrderInfo order = orderService.findOrder(searchCriteria)
return ResponseEntity.ok(order);
而且,在你的服务中,为了避免一堆if
-else
,你可以使用query by example:
public OrderInfo findOrder(SearchOrderCriteria searchCriteria)
OrderInfo order = new OrderInfo();
order.setItemId(searchCriteria.getItemId());
order.setOrderId(searchCriteria.getOrderId());
order.setDeliveryId(searchCriteria.getDeliveryId());
order.setPacketId(searchCriteria.getPacketId());
Example<OrderInfo> example = Example.of(order);
return orderRepository.findOne(example);
【讨论】:
我喜欢这种方法,但也许我还不了解整个情况:) 我仍然很困惑如何根据获取端点中的查询参数来填充SearchCriteria
中的字段?
@lapadets 查看 Spring Data 文档以获取有关 query by example 工作原理的更多详细信息。
谢谢!你的回答对我帮助很大!【参考方案2】:
我的小建议是避免使用过于通用的 API,例如您可以将映射拆分为多个端点,例如:/order/delivery/itemId/itemId 和 /order/delivery/deliveryId/deliveryId 和 /order /delivery/packetId/packetId 并处理您需要在客户端调用的。
【讨论】:
感谢您的建议 - 我通常也会这样做,但问题是它需要是一个端点并且不会从多个客户端调用。 在这种情况下,您可以将所有参数放入非空值的列表过滤器中,例如:List以上是关于您将如何使用 Spring Boot 处理仅具有可选查询参数的 REST API?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Boot Actuator 构建 RESTful Web 服务
如何在具有 JDBC 安全性的 Spring Boot 中使用 Flyway?
如何使用spring boot plugin 2.0.x从一个具有不同依赖项的gradle项目生成2个jar