REST API upsert端点与创建和更新端点有何不同?

6

我正在编写一个REST API,其中包括创建/更新/删除用户。

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

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

12

这里有很多错误的假设。在REST中,一个终端点(endpoint)代表的是一个“事物”,而不是一个“操作”。

假设这个“事物”是一个用户。你可能将一个用户托管在诸如以下URI之类的位置:

http://example.org/users/roy

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

DELETE /users/roy
想要更新它吗?
PUT /users/roy

想要取回它吗?

GET /users/roy

请注意,PUT方法通常被认为比PATCH方法更符合RESTful的原则。如果您严格按照REST的要求实现API,那么最好使用PUT方法。我认为,在问题讨论中将PUT方法与PATCH方法进行区分和比较并不太相关。

现在你还剩下一个动作... 如何创建新用户?嗯,我会总结出以下最佳实践:

如果您可以允许客户端确定URI,则应该使用PUT方法。

PUT /users/roy - Should respond with a 201.

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

我想说上面的做法是最佳实践,但并不常见。通常rest服务都由一些关系数据库支持,而在URI中经常使用整数而不是自然键。

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

/users/1234

这也意味着在创建新资源时,客户端无法知道URI将是什么。通常的解决方法是不要使用 PUT 进行创建,而是使用某种集合资源并使用 POST 来创建新用户:

POST /users/

一个好的API应该返回一个Location标头,其中包含新创建资源的URI。一个好的客户端将知道每当它接收到一个非安全方法后的Location标头时,它应该清除该URI的缓存。


谢谢Evert!只有一个问题,您建议在更新时使用PUT而不是PATCH吗?假设我只更改特定字段..此外,使用PUT创建新用户? - Roy
@Roy。REST的理念是通过网络传输完整的表现形式,而不是部分的表现形式。虽然PATCH可能适用于您的用例,但它不符合RESTful标准,也不是幂等的。我不会告诉你哪个更好,我认为这与问题无关。我不明白你对PUT的问题。 - Evert
@Evert 先生说得好。 - Rabin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接