在 REST 中实现 PUT 的正确方法是什么?

What is the correct way to implement PUT in REST?

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

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

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

当后端在 URL(如 /user/foo 和 http 负载中获取用户名时,处理这种情况的正确方法是什么喜欢:

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

我应该 return 409 - 冲突 还是应该使用负载中的用户名创建或更新用户?

在最初的REST概念中,URL实际上应该是URI——资源标识符,也就是说,在系统中唯一标识您的用户实体。

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

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

长话短说:

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

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

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

中的相同

如果不一致,我会 return 状态 HTTP 422 Unprocessable Entity - 请求格式正确,但由于语义错误无法遵循。 这恰好描述了语义不一致 - JSON 有效载荷的结构是正确的,但语义上 URL 中的 idusername 与有效载荷不匹配。