【问题标题】:Best practice of creation GET methods with many parameters(filters)使用许多参数(过滤器)创建 GET 方法的最佳实践
【发布时间】:2021-03-07 01:23:01
【问题描述】:

我的 Spring REST 控制器中有 GET 方法。此方法通过过滤器返回用户列表。 我有几种方法来实现它:

  1. 添加@PathVariable like - /users/{type}/{age}/{name}/...(在这种情况下是不好的方法)
  2. 添加@RequestParam like - /users?type=type,age=age,name=name...(本例中的常用方法)
  3. 像这样使用 RequestDto(最好的方法)
     public class UsersRequestDto {
        private String type;
        private int age;
        private String name;
        ...
        }

但我不能为此使用 GET 方法。我必须使用 POST 方法和@RequestBody

而且它违反了规则。我的方法不会改变状态,也不会创建任何实体。它作为 GET 方法工作,但实际上是 POST

我有两种方法:

  1. 使用带有许多参数的 GET 方法
  2. POST 方法与 DTO 一起使用,该方法用作 GET 方法并让用户感到困惑。

哪种方式更好?

【问题讨论】:

    标签: spring spring-boot rest http spring-restcontroller


    【解决方案1】:

    您在查询中包含了多少不同的参数?

    就个人而言,我更喜欢带有许多不同参数的 GET 方法选项。它还有其他好处,例如可缓存。此外,将其与 Google 搜索生成的 URL 进行比较 - 大量查询字符串参数。

    POST 选项感觉很脏 - 它违反了 POST 实际应该做的事情(创建或更新资源)。

    查看这些讨论:https://softwareengineering.stackexchange.com/questions/233164/how-do-searches-fit-into-a-restful-interfaceREST API Best practices: Where to put parameters?

    【讨论】:

    • 是的,我知道The POST option feels dirty - it's a violation of what a POST should actually do (creating or updating a resource). 它促使我提出这个问题。但是使用 DTO 看起来很糟糕——您可以更改 DTO 而不要更改 API 方法签名
    • 我记得还有一个选项 - 在 POSTrequest 中您可以隐藏参数并且不在搜索栏中显示它(内部 ID、一些详细信息)
    【解决方案2】:

    首先,当您使用 RequestParam 时,将使用 & 符号而不是逗号 (,) 添加键。

    当您想要过滤(如您所提到的)某些内容时,最好的方法是使用 RequestParam。

    要最小化代码,您可以选择“MultiValueMap”或“HttpservletRequest”。

    1)HttpServletRequest

    @GetMapping("/user")
        public List<User> getFilteredUser(HttpServletRequest httpservlet)
        httpservlet.getQuesryString()   //will return all request param.
    

    2)多值映射

    @RequestParam MultiValueMap<String,String> params
    

    注意:- 一般 POST 用于创建/更新记录。

    【讨论】:

      【解决方案3】:

      短版:您可能正在寻找How to bind @RequestParam to object in Spring。 (另见:https://stackoverflow.com/a/16942352/54734

      在网络上,我们将有一个带有 GET 操作的 html 表单。提交表单时,浏览器将处理输入控件并创建表单数据的 application/x-www-form-urlencoded 表示。对于 GET 操作,该表示用作查询字符串。

      使用 GET 并将所有信息编码到查询字符串中,我们可以利用结果的通用缓存。

      但查询参数本身无法访问 - 它们实际上嵌入在更大的 HTTP 请求上下文中。我们通常不会看到这种情况,因为再一次,通用组件可以完成很多繁重的工作。

      因此,我们看不到从请求中提取目标 uri 的解析器,也看不到将目标 URI 拆分为其单独组件的解析器,也看不到将查询部分拆分为键值对序列的解析器。 ...

      一般来说,我们所做的就是尽可能地使用“通用”实现,然后下车并自己完成剩下的工作。如果框架没有为对象映射提供更好的支持,那可能意味着我们自己实现该映射。

      因此,如果我们的框架缺乏将查询字符串直接映射到对象表示的能力,我们将自己手动滚动实现的那部分(通过“手动”复制每个参数,或者编写我们自己的反射代码来执行自动映射)。

      但似乎 Spring 已经内置了该功能;并且它是默认选项(不需要注释);您只需要确保对象实现提供了 Spring 执行映射所需的接口。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-26
        • 2015-08-10
        • 1970-01-01
        • 1970-01-01
        • 2016-07-03
        • 2015-11-16
        • 2017-05-28
        相关资源
        最近更新 更多