REST API设计指南

时间:2013-04-17 03:39:13

标签: rest api-design

我正在为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?

5 个答案:

答案 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:

POST

http://localhost/api/campaignruns

注意复数名词(更多RESTful,collection-> instance-> collection-> instance ...)。

此请求会创建 campaignrun 。假设 campaignrun 创建的ID为1。

POST

http://localhost/api/campaignruns/1/operations

{
    "operation": "execute"
}

POST

http://localhost/api/campaignruns/1/operations

{
    "operation": "abort"
}
  • 操作 API支持以下HTTP方法: GET,POST
  • 操作 API可能会实现为异步调用(返回202 Accepted)。

假设 abort 操作ID为2。

这是它在 POST 后立即显示(假设异步操作):

GET

http://localhost/api/campaignruns/1/operations/2

Response:

{
    "id": 2,
    "operation": "abort",
    "status": "processing"
}

完成后它应该如何显示:

GET

http://localhost/api/campaignruns/1/operations/2

Response:

{
    "id": 2,
    "operation": "abort",
    "status": "completed"
}