REST API upsert 端点与创建和更新端点

Roy*_*Roy 5 api rest node.js

我正在编写一个 REST API,其余的处理创建/更新/删除用户。

编写创建/更新用户端点的最佳实践是什么?

  1. 一个处理创建和更新(=upsert)用户 POST 请求的端点。
  2. 两个不同的端点 - 一个处理创建用户 POST 请求,另一个处理更新用户 PATCH 请求。

Eve*_*ert 8

这里有很多错误的假设。使用 REST,端点代表“事物”而不是“动作”。

让我们说这个东西是一个用户。您可以在 uri 下托管用户,例如:

http://example.org/users/roy
Run Code Online (Sandbox Code Playgroud)

从这里开始,所有的动作都变得自然。想删除用户?

DELETE /users/roy
Run Code Online (Sandbox Code Playgroud)

想要更新吗?

PUT /users/roy
Run Code Online (Sandbox Code Playgroud)

想要找回吗?

GET /users/roy
Run Code Online (Sandbox Code Playgroud)

请注意,通常认为 PUT 比 PATCH 更 RESTful。如果您严格要求 REST,那么实施 PUT 是个好主意。我认为 PUT 与 PATCH 的区别和好处有点偏离主题。

现在您还剩下一项操作……您如何创建新用户?好吧,我将最佳实践总结如下:

如果您可以让客户端确定 URI,您可能应该使用 PUT。

PUT /users/roy - Should respond with a 201.
Run Code Online (Sandbox Code Playgroud)

如果你想确保你真的创建了一个新用户而不是覆盖一个旧用户,你可以让客户端使用If-None-Match: *标头来强制服务器在资源已经存在的情况下拒绝请求。

我会说以上是最佳实践,但不是最常见的。通常休息服务由一些关系数据库支持,并且在 URI 中经常使用整数而不是自然键。

这意味着您的网址模式看起来像

/users/1234
Run Code Online (Sandbox Code Playgroud)

这也意味着客户端无法知道创建新资源时的 URI 是什么。典型的解决方法是不PUT用于创建,而是使用某种集合资源并用于POST创建新用户:

POST /users/
Run Code Online (Sandbox Code Playgroud)

一个好的 API 可能会返回一个Location包含新创建资源的 uri的标头。一个好的客户端会知道,每当它Location在一个非安全方法之后收到一个标头时,它应该清除它的 uri 缓存。