我正在为REST接口设计公共API。其中一件事就是使用http动词,特别是DELETE动词。
我们希望公开启动/停止或执行/中止特定作业的方法。这两种api设计的两种风格是:
发表
http://localhost/api/campaignrun/1
执行ID为1的广告系列
删除
http://localhost/api/campaignrun/1
以id为1
中止广告系列...替代地
发表
http://localhost/api/campaignrun/1
{ action=execute}
执行ID为1的广告系列
发表
http://localhost/api/campaignrun/1
{ action=abort }
中止广告系列的ID为1
如果有我最喜欢的,哪一个更RESTful?
答案 0 :(得分:2)
在您的两个设计之间选择我会投票支持您的第二个设计,使用POST
,但稍作修改:使用PUT
代替:
PUT http://localhost/api/campaignrun/1
{ action: abord }
这个API明确说明了它的意图:你有campaignruns
(更好地保持这个复数),你想要拥有{id} = 1
的campainrun,并且有一个属性该资源称为操作,我想更新。
这样,您就可以保持API与http谓词的idempotence一致:PUT
应该是幂等的,POST
不应该。对于您的情况,这意味着,无论用户点击上述请求多少次,结果都是相同的:id = 1的campaignrun将被取消。
注意:我看到你接受了一个在URI上提出动词的答案,然后对它们使用POST
。这篇文章不是争论或反对REST的地方,但由于你的问题是关于哪个设计更加RESTful ,你应该三思而后行。您可能想要查看这个非常好的38页免费ebook,其中介绍了设计API的最佳实践。除其他外,它建议将动词保留在您的基本URL 之外,除非极少数情况。检查出来,这将证明是有帮助的!
答案 1 :(得分:0)
第一个更“宁静”。您将遇到的唯一问题是,如果您需要删除而不是中止将来运行的广告系列。如果您将来需要广告系列运行删除记录功能,则始终可以将操作传递给DELETE。
答案 2 :(得分:0)
如果你可以使用DELETE,那就太好了。但是,您应该只在停止广告系列运行时才这样做,这意味着客户端永远不应再次访问该资源(该特定网址)。如果合理地期望客户端事后与资源交互,请使用POST(或者当然是PUT到子资源)。
答案 3 :(得分:0)
是否可以重新启动已停止的作业?如果是这样,我建议你使用POST
,因为你并没有真正删除任何资源。但是,您可以更改网址以更好地指出您要实现的目标:
发表强>
http://localhost/api/campaignrun/1/start
和
发表强>
http://localhost/api/campaignrun/1/stop
因此,无需提供请求正文来指明行动的类型。
附注:对我来说DELETE
表示该广告系列将永久删除,因此无法重新启动。因此,如果客户端尝试访问资源,将返回404。
答案 4 :(得分:0)
正如许多人在此处所述,资源上的DELETE意味着不再可访问相关的 campaignrun (404 Not Found应该在之后返回)。 我猜这不是意图中止 campaignrun 。
以下内容将与问题中提到的任何替代方案更符合REST:
http://localhost/api/campaignruns
注意复数名词(更多RESTful,collection-> instance-> collection-> instance ...)。
此请求会创建 campaignrun 。假设 campaignrun 创建的ID为1。
http://localhost/api/campaignruns/1/operations
{
"operation": "execute"
}
http://localhost/api/campaignruns/1/operations
{
"operation": "abort"
}
假设 abort 操作ID为2。
这是它在 POST 后立即显示(假设异步操作):
http://localhost/api/campaignruns/1/operations/2
Response:
{
"id": 2,
"operation": "abort",
"status": "processing"
}
完成后它应该如何显示:
http://localhost/api/campaignruns/1/operations/2
Response:
{
"id": 2,
"operation": "abort",
"status": "completed"
}