我正在编写一个REST API,其中包括创建/更新/删除用户。
写创建/更新用户端点的最佳实践是什么?
- 一个端点处理同时包含创建和更新(= upsert)用户的POST请求。
- 两个不同的端点 - 一个处理创建用户的POST请求,另一个处理更新用户的PATCH请求。
这里有很多错误的假设。在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的缓存。