我正在实现REST API,并希望输入一些严格不适合CRUD模型的方法。这是一个通用示例:
我将“狗”对象发布到我的“狗”集合中。 我在新狗(dogs / 1)上搭上项圈。 我现在要让狗翻身。
假设“翻身”是一项一次性任务,不会改变狗的状态,那么您将如何实现呢?我有以下想法:
选项1:
POST dogs/1
{
task: "roll over"
}
选项2:
POST tasks/
{
task: "roll over"
id: 1
}
选项3:
GET dogs/1/rollOver
答案 0 :(得分:1)
假设“翻身”是一项一次性任务,不会改变狗的状态,那么您将如何实现呢?
简短答案:
POST /tasks
{
"task": "roll over",
"id": "/dogs/1"
}
更长的答案:REST的重要限制之一是统一的接口-包括以下事实:自描述消息的语义对于世界各地的所有资源都是相同的。
GET
是“启动任务”的糟糕方法,因为GET的语义是safe,也就是说实际上是只读的,这意味着任何地方的任何人都可以在以下位置请求该资源的表示形式任何时候。考虑使用浏览器预先获取任务链接以节省时间,或者考虑使用网络爬虫来添加任务资源以进行索引。
在两者之间可以选择
POST /dogs/1
POST /tasks
现在,由于POST是一种不安全的方法,因此需要考虑一个有趣的缓存问题。对不安全请求的非错误响应将invalidate缓存目标资源的表示形式。
通常,如果您要更改资源(例如:PUT / foo),则完全是您想要的。
但是在这里,听起来好像“翻转”任务不应该更改/dogs/1
的表示。如果该资源的表示形式不会改变,那么我不想使其无效,而我将通过请求将其他资源作为目标。
当然,/tasks
的拼写没有什么特别的魔术。就像/dogs/1/tasks
或/tasks/dogs/1
或/dogs/1/rollOver
或/b79d1e50-44eb-4c51-bfc6-ef0d94c15fdc
一样容易。