【问题标题】:Restful API - how close to get,put,post,delete does it need to be?Restful API - 需要多接近获取、放置、发布、删除?
【发布时间】:2017-11-20 19:37:20
【问题描述】:

我在 Spring 中设置了一个 API,客户端可以在其中指定他们想要接收的对象的 id。它返回对象的 JSON 列表(使用 @ResponseBody 注释)。

但是,由于请求可能是一个很长的列表,我将其设置为 POST,它作为名为 ProductRequest 的对象接收(使用 @RequestBody 注释)。这似乎不符合官方的 REST API 标准,因为帖子是创建新对象的官方标准,但是以这种方式实现它似乎更好,因为您不会用一堆 id 混淆 URL。此外,我可以指定自定义输出的其他参数。

所以我的问题是,这可以被认为是一个有效的 RESTful 设计吗? Post 不是用来创建对象的,所以它并不严格符合 restful。想法?

【问题讨论】:

  • “官方 REST API 标准”是什么意思?
  • 如果可能,您可以指定自己的 HTTP 动词,例如列表。但这并不总是最好的选择。找到了一个简短的讨论here

标签: json spring http post restful-url


【解决方案1】:

这是一个简单的 GET 请求。

@GetMapping(path = "/your-url")
public List<Object> method(@RequestParam(name="ids") List<Long> objectIds) {
}

您可以像一个简单的 java 列表一样接收您的列表。

/api?ids=1,2,3

【讨论】:

  • 问题:如果您的 id 列表包含数百或数千个 12 位标识符怎么办?这不会溢出 URL 字符串的最大允许值吗?我以前遇到过这个。另外,为什么把它变成一个帖子是一件坏事?最终,这就是 API 在这种情况下的工作方式。
  • 我认为此类请求也需要在客户端进行分页,并且在一个请求中请求的对象数量不得超过“固定”数量。但是如果不可能的话,我认为你不能使用HTTP方法GET。
【解决方案2】:

您可以很好地执行 http POST 来“获取”资源。有一些非常有效的例子,

  1. GraphQL -- 我们所做的只是在请求正文中发送(发布)一些查询,以“获取”我们喜欢的格式的一些数据

  2. 假设您必须使用用户名和密码进行身份验证才能获取特定数据,您将在 GET 请求的 Header 中发送它,或者您将执行 POST 以“获取”数据。

【讨论】:

  • 据我所知,我们应该使用GET 方法通过指定query 参数来获取我们喜欢的格式的数据。如果我们需要设置将在资源上执行的操作,则最好使用 POST
  • @AndrewTobilko 感谢评论...当涉及多个资源时,仍然是“GET”操作,没有“副作用”,即使http方法是POST
【解决方案3】:

这不会超出 URL 字符串允许的最大值吗?

实际上,URI 的长度没有限制。但是,实际上,您可以遇到一些。

根据RFC7230(强调我的),

HTTP 对请求行的长度没有预先定义的限制,如第 2.5 节所述。接收到比它实现的任何方法更长的方法的服务器应该以501 (Not Implemented) 状态码响应。接收到比它希望解析的任何 URI 更长的请求目标的服务器必须以 414 (URI Too Long) 状态码进行响应。

在实践中发现了对请求行长度的各种特殊限制。建议所有 HTTP 发送方和接收方至少支持 8000 个八位字节的请求行长度。 p>

这清楚地表明我们在处理您的问题时不能依赖请求热线。

这可以被认为是有效的 RESTful 设计吗?

由于上述限制,使用POST 是一种有效的解决方法

this Wikipedia article所述,

这些问题的常见解决方法是使用POST 而不是GET 并将参数存储在请求正文中。请求正文的长度限制通常远高于 URL 长度。

为了让您完全摆脱犹豫,有一个common non-standard header X-Http-Method-Override。它请求 Web 应用程序使用标头中给出的方法覆盖请求中指定的方法:

X-Http-Method-Override: GET

我不确定 Spring 是否处理标题。不过,它有 HiddenHttpMethodFilter 过滤器,似乎可以做类似的工作。

【讨论】:

    猜你喜欢
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 2022-10-20
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多