Spring REST API 多个 RequestParams 与控制器实现

inv*_*sus 4 java api rest spring spring-boot

我想知道在给定多个请求参数的 GET 请求的情况下实现控制器的正确方法。根据我对 REST 的理解,拥有一个带有用于过滤/排序的附加参数的端点比使用多个端点(每种情况一个)要好得多。我只是想知道此类端点的维护和可扩展性。请看下面的例子:

@RestController
@RequestMapping("/customers")
public class CustomerController {

    @Autowired
    private CustomerRepository customerRepo;

    @GetMapping
    public Page<Customer> findCustomersByFirstName(
                @RequestParam("firstName") String firstName,
                @RequestParam("lastName") String lastName,
                @RequestParam("status") Status status, Pageable pageable) {

        if (firstName != null) {
            if (lastName != null) {
                if (status != null) {
                    return customerRepo.findByFirstNameAndLastNameAndStatus(
                                                    firstName, lastName, status, pageable);
                } else {
                    return customerRepo.findByFirstNameAndLastName(
                                                    firstName, lastName, pageable);
                }
            } else {
                // other combinations omitted for sanity
            }
        } else {
            // other combinations omitted for sanity
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样的端点似乎使用起来非常方便(参数的顺序并不重要,所有这些都是可选的......),但是维护这样的东西看起来就像地狱(组合的数量可能是巨大的)。

我的问题是 - 处理此类事情的最佳方法是什么?“专业”的API是如何设计的?

Ala*_*Hay 5

处理这样的事情最好的方法是什么?

处理这个问题的最佳方法是使用现有的工具。当您使用 Spring Boot 时,我假设 Spring Data JPA 然后为 Spring Data JPA 启用 QueryDsl 支持和 Web 支持扩展。

然后你的控制器就变成了:

@GetMapping
public Page<Customer> searchCustomers( 
        @QuerydslPredicate(root = Customer.class) Predicate predicate, Pageable pageable) {
   return customerRepo.findBy(predicate, pageable);
}
Run Code Online (Sandbox Code Playgroud)

并且您的存储库只需扩展以支持 QueryDsl:

public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long>, 
            QueryDslPredicateExecutor<Customer>{

}
Run Code Online (Sandbox Code Playgroud)

您现在可以通过参数的任意组合进行查询,而无需编写任何进一步的代码。

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web.type-safe https://docs.spring.io/spring-data/jpa/docs/当前/参考/html/#core.extensions.querydsl