返回也是集合的资源表示的最佳实践
假设我想创建一个RESTful接口,并且我想根据它们的IDs使用foo
。这里没有新东西:返回也是集合的资源表示的最佳实践
-
GET /api/foo1
返回foo1
的表示(例如使用JSON)。 -
DELETE /api/foo1
删除foo1
。
等
现在让我告诉你,“富”是一个集合类型的事情。所以,我希望能够以“条”添加到“富”:
-
PUT /api/foo1/bar3
增加bar3
到foo1
。 -
GET /api/foo1/bar3
返回foo1
的表示形式。 -
DELETE /api/foo1/bar3
从foo1
删除bar3
。 -
DELETE /api/foo1
共删除foo1
。
现在问题仍然存在:GET /api/foo1
做什么?它是否像我最初在这个问题中假设的那样简单地返回foo1
的表示形式?还是它返回一个酒吧列表?或者它是否返回表示foo1
既是foo1
的描述以及包括所有包含的酒吧列表?
还是应该GET /api/foo1
仅仅返回foo1
表示如我在开始时假定,并要求PROPFIND
请求,要求列内foo1
(通过WebDAV的所采用的方法)的棒?但是为了保持一致,我是否不必将所有其他列表类型的功能都更改为PROPFIND
,这直接违背了成千上万的REST教程,这些教程使用GET /api/foo1
来列出内容?
webdav的语义从来没有真正符合RESTful接口的习语。
理论上,GET应该检索资源状态的表示,并且PROPFIND应该用于检索集合的成员。
所以,你应该这样做:
- GET/API/foo1/- 回报foo1的状态只
- PROPFIND/API/foo1/- 返回foo1
成员大多数如果你告诉他们使用PROPFIND,前端开发人员会吓坏了,尽管它在浏览器js实现中完全支持。
我个人使用WebDAV/JSON网关,其中请求使用REST风格的成语制成,但排到我的WebDAV实现
例如,我会做到这一点:
GET /api/foo1/_PROPFIND?fields=name,fooProp1,fooProp2
这将返回
[
{ name : "bar1", fooProp1: "..", fooProp2 : ".."},
{ name : "bar2", fooProp1: "..", fooProp2 : ".."}
]
这种方法的一个优点是客户端可以控制返回的json属性。这很好,因为丰富的API会有很多属性,但在大多数情况下,客户端并不需要所有这些属性。
RESTfull API中的路由及其操作完全由开发人员设计。开发者在请求特定路线时决定返回什么,例如GET /api/foo1
。
而且开发者应该设计每条路线,包括/api/foo1/bar
。没有关于特定路线应该做什么的具体规则。如果您的API是一个开源项目,请为每条路线制定清晰明了的文档。
不要浪费你的时间思考旧的学校策略。
经过一番思考,我认为从RESTful的角度来看最好的概念性解释是,通常这个“东西”与它的“集合”不是一回事。因此,在WebDAV世界中,directory/
可能与保存其文件的东西是一样的,但在RESTful世界中,我可能会为包含的文件单独使用directory/files/
子路径。这样我就可以分别操作与保存的文件不同的目录。
考虑一个包含谷仓的农场的RESTful API。端点farm/api/barns/
可能会返回一列谷仓,其中一个谷仓将是farm/api/barns/bigredbarn
。天真地我会认为检索farm/api/barns/bigredbarn/
会给我提供一个谷仓里的动物列表,这就是引发这个问题的原因。
但谷仓里的动物真的只是大红谷仓的一个方面。它可能包含车辆和干草:
farm/api/barns/bigredbarn/animals/
farm/api/barns/bigredbarn/vehicles/
farm/api/barns/bigredbarn/haybales/
有了这个方法,我所面临的困境并不存在。
我喜欢你的方法。事实上,这是相同的行为,真正面向对象的语言实现对数组或对象列表: Array对象的属性:长度,尺寸,只读 阵列方法GetValue - 返回一个项目 List对象的属性:头部,当前 列表方法GetEnumerator - 返回一个对象,该对象又将返回项目 –