api - REST API 任务的最佳实践(不是 CRUD)
问题描述
我正在实现一个 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
解决方案
假设“翻身”是一项不会改变狗状态的一次性任务,您将如何实现呢?
简短的回答:
POST /tasks
{
"task": "roll over",
"id": "/dogs/1"
}
更长的答案:REST 的重要约束之一是统一接口——其中包括自描述消息的语义对于任何地方的所有资源都是相同的这一事实。
GET
是一种糟糕的“开始任务”方式,因为 GET 的语义是安全的,也就是说有效地只读,这意味着任何地方的任何人都可以随时请求该资源的表示。考虑浏览器预先获取任务链接以节省时间,或者网络爬虫来添加您的任务资源以进行索引。
这留下了一个选择
POST /dogs/1
POST /tasks
现在,因为 POST 是一种不安全的方法,所以需要考虑一个有趣的缓存问题。对不安全请求的非错误响应将使目标资源的缓存表示无效。
通常,如果您要更改资源(例如:PUT /foo),这正是您想要的。
但是在这里,听起来“翻转”任务不应该改变/dogs/1
. 如果该资源的表示不会改变,那么我不想使其无效,而是将请求定位到其他一些资源。
当然,拼写并没有什么特别神奇的地方/tasks
。它可以很容易地是/dogs/1/tasks
, or /tasks/dogs/1
or /dogs/1/rollOver
or /b79d1e50-44eb-4c51-bfc6-ef0d94c15fdc
。
推荐阅读
- typescript - 当枚举存在于不可变记录中时,打字稿错误
- c - 联合与价值
- r - 将 Rmd 编织为 PDF 时 knitr 出错,但代码运行良好?
- firebase - 使用 FFMPEG 将多个视频合并为分屏视频
- log4j - 如何基于多个动态参数在 Log4j2 中以编程方式创建多个日志文件?
- python - 检查可以由另一个单词组成的可能单词数量的函数(Python 3.6)
- sql - 无法理解使用 where 和 group by 的子查询代码
- javascript - 强制 Vue 重新渲染具有已移除属性的元素
- java - Java:通过在初始化期间返回现有类来防止重复类
- frameworks - forkdelta 的前端使用什么框架?