我的应用程序有一个资源/foo
。通常,它由如下所示的 HTTP 响应负载表示:
{"a": "some text", "b": "some text", "c": "some text", "d": "some text"}
客户端并不总是需要该对象的所有四个成员。客户端告诉服务器它在表示中需要什么的RESTful 语义方式是什么?例如,如果它想要:
{"a": "some text", "b": "some text", "d": "some text"}
应该怎么做GET
呢?一些可能性(如果我误解了 REST,我正在寻找更正):
GET /foo?sections=a,b,d
.- 查询字符串(毕竟称为查询字符串)似乎意味着“找到符合此条件的资源并告诉我它们”,而不是“根据此自定义向我表示此资源”。
GET /foo/a+b+d
如果 REST 语义没有涵盖这个问题,我最喜欢它,因为它很简单。- 打破 URI 不透明度,违反 HATEOAS。
- 似乎打破了资源(URI 的唯一含义是标识一个资源)和表示之间的区别。但这是值得商榷的,因为它与
/widgets
表示一个可展示的/widget/<id>
资源列表是一致的,而我从来没有遇到过这个问题。
- 放松我的约束,响应等,并让客户端根据它想要
GET /foo/a
的组件发出请求。/foo
- 增加开销,如果
/foo
有数百个组件并且客户端需要其中的 100 个,这可能会成为一场噩梦。 - 如果我想支持 的 HTML 表示
/foo
,我必须使用 Ajax,如果我只想要一个可以被极简浏览器抓取、呈现等的 HTML 页面,这是有问题的。 - 为了维护 HATEOAS,它还需要到那些“子资源”的链接存在于其他表示中,可能在
/foo
:{"a": {"url": "/foo/a", "content": "some text"}, ...}
- 增加开销,如果
GET /foo
,Content-Type: application/json
并{"sections": ["a","b","d"]}
在请求正文中。- 不可标记且不可缓存。
- HTTP 没有为
GET
. 这是合法的 HTTP,但我如何保证某些用户的代理不会从GET
请求中删除正文? - 我的REST 客户端不允许我在
GET
请求中添加正文,因此我无法将其用于测试。
- 自定义 HTTP 标头:
Sections-Needed: a,b,d
- 如果可能的话,我宁愿避免使用自定义标题。
- 不可标记且不可缓存。
POST /foo/requests
,Content-Type: application/json
并{"sections": ["a","b","d"]}
在请求正文中。收到一个201
.Location: /foo/requests/1
然后GET /foo/requests/1
接收所需的表示/foo
- 笨重;需要来回和一些看起来很奇怪的代码。
- Unbookmarkable and uncacheable since
/foo/requests/1
只是一个别名,只能使用一次,并且只保留直到被请求。