【问题标题】:What is the correct way to implement PUT in REST? [closed]在 REST 中实现 PUT 的正确方法是什么? [关闭]
【发布时间】:2019-07-26 05:11:46
【问题描述】:

我可以在 /user/{username} URL 上获取用户的数据并且响应是

{
  "id" : 1,
  "username" : "testuser",
  "email" : "test@example.org"
}

在我的实现中,如果您在 /user/{username} URL 上放置数据,后端将使用指定的用户名创建或更新用户。

当后端在 /user/foo 之类的 URL 和 http 有效负载中获取用户名时,处理这种情况的正确方法是:

{
  "id" : 1,
  "username" : "bar",
  "email" : "test@example.org"
}

我应该返回 409 - Conflict 还是应该使用负载中的用户名创建或更新用户?

【问题讨论】:

  • 这个问题是见仁见智的问题,所以这是我的问题。您不应允许通过两个不同的操作进行相同的操作。我构建它的方式是在 /user 上实现 PUT 以创建新用户,并在 /user/{username} 上实现 PATCH 以进行更新。任何请求都不应包含重复的参数,无论是在 URL 还是 HTTP 负载中。

标签: rest http url httpverbs


【解决方案1】:

在最初的REST 概念中,URL 应该是 URI - 资源标识符,也就是说,唯一标识系统中的 user 实体。

因此,如果在您的模型中username唯一的,并且不可能有 2 个同名用户,那么您可以在 资源标识符中使用 username 网址。 示例 - /user/foo

但是,如果有可能 2 个具有不同 id 的用户可以拥有相同的 username,那么根据 strict REST 你不能使用 username 作为 URL 的一部分 - 它不会不再是 REST,只是一些在 PUT 请求的负载中接受 JSON 的 Web 服务。

长话短说:

1) 如果 username 不是您系统中用户的唯一标识符 - 不要在 URL 中使用它,请改用 id,例如您提到的 URL 将是 /user/1

2) 如果username 是您系统中的唯一标识符 - 那么您可以拥有/user/foo

================================================ ==============================
在这两种情况下,您都需要检查有效负载中的值是否与 URL 中的值相对应:
对于 1) 您检查 URL 中的 id 是否与有效负载中的相同
对于 2) 您检查 URL 中的 username 是否与有效负载中的相同

如果不一致,我会返回状态HTTP 422 Unprocessable Entity - 请求格式正确,但由于语义错误而无法执行。 这准确描述了语义不一致 - JSON 有效负载的结构是正确的,但在 URL 和有效负载中语义上的 idusername 不匹配。

【讨论】:

    猜你喜欢
    • 2016-08-31
    • 2023-04-09
    • 2011-11-06
    • 2018-08-12
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    相关资源
    最近更新 更多