想象一下,例如绑定表user_tasks(user_id, task_id)与m:n关系,我想插入新的记录。如果该记录被插入或者该记录已经存在,端点应该返回204状态No Content。你会如何编写这样的端点?
GET users/{user_id}/tasks/{task_id}
POST users/{user_id}/tasks/{task_id}
PUT users/{user_id}/tasks/{task_id}
PUT user_tasks + payload: {"user_id": 1, "task_id": 2}
我个人会选择GET,因为方法是幂等的(如果我理解正确的话),而且它不包含有效载荷,但我不确定。
GET users/{user_id}/tasks/{task_id}/position/{position}
POST user_tasks + payload: {"user_id": 1, "task_id": 2, "position": 3}
POST users/{user_id}/tasks/{task_id} + payload: {"position": 3}
PUT users/{user_id}/tasks/{task_id} + payload: {"position": 3}
在我们的项目中,这两种情况都有。
看起来像 PUT
将更适合你的任务 GET
,只是因为 GET
不应该修改服务器上的状态。从 RFC 2616:
GET方法是指检索由Request-URI识别的任何信息(实体形式)。
也是从那里开始的。
安全方法。特别是,已经确定的惯例是,GET和HEAD方法不应具有采取检索以外的行动的意义。这些方法应该被认为是 "安全的"
另一方面,对于PUT。
PUT方法要求将所附实体存储在所提供的Request -URI下。如果Request-URI指的是 现有资源在这里,被包围的实体应该被认为是原服务器上的实体的修改版。
这似乎很合适,因为这里提到了一些资源已经存在的可能性,我们可能不想再次创建它。PUT
也被认为是幂等的。
现在想象一下,这个表还有一列:user_tasks(user_id, task_id, position)。这里最好的解决方案是什么?
最好的解决方案无处不在,就是选择最适合你和API用户的方法。这里唯一可能的缺点可能是,提到的两种方案中的一种与API中的其他方案不相似,有些用户会觉得意外。
就个人而言,我会选择 PUT users/{user_id}/tasks/{task_id}/assign?position=3
或者用你的方法,参数通过payload传递。我认为URI应该是一些可识别的资源,而 user_tasks
看起来不像。它看起来像一个动作名称,通常可以在URI的末尾看到,例如,看一下 如何 Twitter做到了这一点。