在REST API中设计动作 - 什么时候RESTful太RESTful了?

App*_* S. 22 rest specifications

我正在为我们正在开发的项目设计REST API.也就是说,我正在编写将在稍后实施的规范.

我在考虑名词/资源而不是动作/动词时遇到麻烦.在没有涉及太多项目细节的情况下,我们正在围绕SVN编写API.例如,采取提交更改的操作到SVN服务器.在我们的项目中,我们有多个提交操作的定义/版本:

  • 只需提交所有已更改的文件
  • 提交已更改文件的列表(子集,而不是整组已更改的文件)
  • ...

(1)您将如何设计URL?第一个问题是,如何将提交操作描述为名词/资源而不是动词

有人会说:

POST/PUT http://server.com/api/revision/commit
Run Code Online (Sandbox Code Playgroud)

应该是POST还是PUT?我不是真的在创建一个提交资源,所以它不是一个POST.但是,我并没有真正更改提交资源,因此它不是PUT.实际上,它不是一种资源,而是一种行动.一旦执行了操作,它就会消失,没有资源可以创建,更改或保留供以后参考.

也就是说,它必须是一个资源,所以URL应该是这样的

POST http://server.com/api/revision/commitment
Run Code Online (Sandbox Code Playgroud)

它也是一个POST,因为我们正在创建一个承诺.我们没有改变任何东西,所以没有PUT.另请注意,我将承诺更改为承诺,以反映我们正在处理资源的事实.

这有意义吗?对我而言,它没有,它让我疯了.我想执行一个动作,而不是创建一个类似于动作的资源.但无论如何.

也就是说,进一步说,我刚刚创建了一个承诺资源.从逻辑上讲,我应该可以在以后检索它:

GET http://server.com/api/revision/commitment/:id
Run Code Online (Sandbox Code Playgroud)

但是没有承诺资源!为了成为RESTful,我被迫制作一个.头部爆炸

那么,您如何真正指定REST API中的资源操作?我不是在谈论创建资源的行为(创建用户,......),而是关于操纵资源或对资源采取行动的行为(提交修订,......).

(2)然后,其次,在第二个定义的情况下(见上文),我们如何指定已更改文件的子集?通过参数或在BODY中的某些结构(例如JSON数组)?哪一个更受欢迎?有没有一般规则?

谢谢大家!

fum*_*chu 14

有时,在URL设计中备份比在未来更容易.在我看来,你所谓的"承诺"实际上是一个修订本身.svn commit基本上是指,"请接受我目前选择的修订版中的这些差异作为新的(子)修订版".因此,您需要识别当前选定的修订版本(为了保持无状态),然后以有意义的方式附加到它:

POST http://server.com/api/revisions/16/children/
Run Code Online (Sandbox Code Playgroud)

也就是说,POST一个实体,它封装了与修订版16的差异.然后,服务器可以响应201 Created,加上Location: /api/revisions/23/(或/api/revisions/16/children/1重定向到前者).

然后,您不仅提供了新修订的创建,而且还很可能添加了给定修订的直接子项的有用列表.