【问题标题】:Questions on proper REST api design specifically on the PUT action when updating a resource关于正确 REST api 设计的问题,特别是在更新资源时 PUT 操作
【发布时间】:2015-02-21 12:23:29
【问题描述】:

我正在创建一个 REST 接口(我们不都是),我想更新一个资源。

所以,我想使用 PUT。

所以,我读了this

我的收获是我把这样的 URL 放到了一个 URL 上

/hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c

使用有效负载,然后永久重定向到它可以获取资源的更新版本的 URL。 在这种情况下,它恰好是相同的 URL,不同的操作。

所以我的问题是:

  1. 在使用 PUT 时我对更新资源的理解是否正确,并且我对 PUT 的使用的理解是否正确。
  2. 当客户端获得重定向时,它对重定向 URL 的操作是否与对原始 URL 的操作相同?如果它的“取决于”是否有大多数客户遵循的标准?

我问第二个问题,因为 POSTMAN 和我的 JQuery AJAX 调用令人窒息。 JQuery 因为 net::ERR_TOO_MANY_REDIRECTS。那么它是否重定向并再次尝试 PUT,它将获得另一个 REDIRECT?

curl 也爆炸了,但即使它说如果它得到一个 301 它将切换到一个 GET,当我查看输出时它似乎并没有这样做(如下)。

当 curl 跟随重定向并且请求不是普通的 GET(例如 POST 或 PUT)时,如果 HTTP 响应为 301、302 或 303,它将使用 GET 执行以下请求。如果响应代码是任何其他 3xx 代码,curl 将使用相同的未修改方法重新发送以下请求。

CURL OUTPUT(为简洁起见进行了编辑)(另请注意它是如何说它将切换到 GET [从 POST 错误地],但它似乎还是做了一个 PUT):

curl -X PUT -H "Authorization: Basic AUTHZ==" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -H "Postman-Token: e80657f0-a8f5-af77-1d9d-d7bc22ed0b30" -d '{ JSONDATA"}' http://localhost:8080/hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c -v -L
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> PUT /hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
> Authorization: Basic AUTHZ==
> Content-Type: application/json
> Cache-Control: no-cache
> Postman-Token: e80657f0-a8f5-af77-1d9d-d7bc22ed0b30
> Content-Length: 203
>
* upload completely sent off: 203 out of 203 bytes
< HTTP/1.1 301 Moved Permanently
< Connection: keep-alive
< X-Powered-By: Undertow/1
< Set-Cookie: rememberMe=deleteMe; Path=/hc; Max-Age=0; Expires=Fri, 20-Feb-2015 03:53:28 GMT
< Set-Cookie: JSESSIONID=uwI3_41LAa7vlvapTsrZdw10.macbook-air; path=/hc
* Server WildFly/8 is not blacklisted
< Server: WildFly/8
< Location: /hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c
< Content-Length: 0
< Date: Sat, 21 Feb 2015 03:53:28 GMT
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c'
* Switch from POST to GET
* Found bundle for host localhost: 0x7f9e4b415430
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
> PUT /hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
> Authorization: Basic dGVzdHVzZXIxOlBhc3N3b3JkMQ==
> Content-Type: application/json
> Cache-Control: no-cache
> Postman-Token: e80657f0-a8f5-af77-1d9d-d7bc22ed0b30
>
< HTTP/1.1 500 Internal Server Error
< Connection: keep-alive
< Set-Cookie: JSESSIONID=fDXxlH2xI-0-DEaC6Dj5EhD9.macbook-air; path=/hc
< Content-Type: text/html; charset=UTF-8
< Content-Length: 8593
< Date: Sat, 21 Feb 2015 03:53:28 GMT
<

...失败随之而来...它实际上做了一个 PUT

提前致谢。

【问题讨论】:

  • 位置为什么会移动?它没有,所以为什么“永久移动”。客户端知道确切的 URL,它不会改变。无需设置 Location 标头或重定向。这主要用于 POST,当您 创建 资源时。据我所知,重定向模式并不是真正的休息练习,而是更多的网络练习,以避免重复提交。基本上你正在做的是一个无限循环。你PUT,重定向回相同的资源,重定向回相同的资源,重定向回相同的资源...
  • 我收回关于成为无限循环的最后一部分。重定向应该 GET。但在这种情况下,他们应该不需要重定向,这就是我要说的重点
  • 对,这没有意义,我读错了。

标签: rest http put


【解决方案1】:

我认为您对 301 重定向部分的阅读过多。

如果要使用 PUT 更新资源,请返回:

  • 201:如果资源已创建
  • 200:使用更新的资源

只有在实际存在重定向问题时,301 才适用 - 例如,如果可以通过名称识别某些内容,并且您需要将其重定向到具有 id 或其他内容的 url。 (也许你重构了,人们仍在使用旧的端点)。

那么,您真的需要重定向您的 PUT 请求吗?因为您应该使用 200 在同一循环中发回更新的资源,如上所述,而不是“重定向到 GET”。

编辑:修正一些拼写。

【讨论】:

  • 我读的太多了,事实上它被分段的方式,我认为“它必须......”是规范中的一个要点,并没有注意到它实际上是一个延续之前的句子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2020-05-07
  • 2017-12-26
相关资源
最近更新 更多