Jor*_*dan 50 api rest url web-applications http
我的应用程序有一个资源/foo.通常,它由HTTP响应有效负载表示,如下所示:
{"a": "some text", "b": "some text", "c": "some text", "d": "some text"}
Run Code Online (Sandbox Code Playgroud)
客户端并不总是需要此对象的所有四个成员.什么是RESTful语义方式,客户端告诉服务器它在表示中需要什么?例如,如果它想要:
{"a": "some text", "b": "some text", "d": "some text"}
Run Code Online (Sandbox Code Playgroud)
应该怎么GET做?一些可能性(如果我误解了REST,我正在寻找纠正):
GET /foo?sections=a,b,d.
GET /foo/a+b+d我最喜欢的REST语义不包括这个问题,因为它简单.
/widgets代表一个可呈现的/widget/<id>资源列表是一致的,我从来没有遇到过这样的问题.GET /foo/a等,让客户端根据需要为每个组件发出请求/foo.
/foo有数百个组件且客户端需要100个组件,这可能会成为一场噩梦./foo,我必须使用Ajax,如果我只想要一个可以被抓取,由极简主义浏览器呈现的HTML页面等,这是有问题的./foo:{"a": {"url": "/foo/a", "content": "some text"}, ...}GET /foo,Content-Type: application/json并{"sections": ["a","b","d"]}在请求正文中.
GET.这是合法的HTTP,但我如何保证某些用户的代理不会从GET请求中剥离正文?GET请求上放置一个正文,所以我不能用它进行测试.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
/foo/requests/1它只是一个只能使用一次的别名,只保留到请求之前.Dan*_*zey 12
我会建议查询解决方案(你的第一个).你反对其他选择的论据是很好的论据(也是我在尝试解决同样问题时遇到的问题).特别是,"放松约束/响应foo/a"解决方案可以在有限的情况下工作,但是从实现和消费中向API引入了很多复杂性,并且根据我的经验,并没有值得付出努力.
我会用一个常见的例子来弱对抗你的"似乎意味着"的论点:考虑一个大型对象列表的资源(GET /Customers).分页这些对象是完全合理的,使用查询字符串来做这件事是很常见的:GET /Customers?offset=100&take=50作为一个例子.在这种情况下,查询字符串不会对列出的对象的任何属性进行过滤,而是为对象的子视图提供参数.
更具体地说,我会说你可以通过这些使用查询字符串的标准来保持一致性和HATEOAS:
但是,为这些Uris 返回的内容有时会带来更复杂的问题:
/foo是一个实体,但是foo/a是一个字符串); 另一种方法是返回一个部分填充的实体/foo没有一个a,一个404状态误导性(/foo 不存在),但是空的响应可能同样令人困惑a是强制的,但客户端仅请求b,则您将被强制返回垃圾值a或无效对象)在过去,我试图通过定义所需实体的特定命名"视图",并允许查询字符串?view=summary或?view=totalsOnly- 限制排列数来解决此问题.这还允许定义对服务的消费者"有意义"的实体子集,并且可以记录.
最终,我认为这可归结为一致性问题:您可以相对轻松地使用查询字符串来满足HATEOAS指导,但您所做的选择需要在您的API中保持一致,并且我会说,有很好的文档记录.
我决定以下几点:
支持少数成员组合:我将为每个组合提供一个名称.例如,如果某篇文章中包含作者,日期和正文的成员,/article/some-slug则会返回所有成员,并且/article/some-slug/meta只返回作者和日期.
支持多种组合:我将用连字符分隔成员名称:/foo/a-b-c.
无论哪种方式,404如果组合不受支持,我将返回a .
资源R是时间上变化的隶属函数M R(t),其对于时间t映射到一组实体或等价的值.集合中的值可以是资源表示和/或资源标识符.
表示为HTTP主体,标识符为URL.
这很关键.标识符只是与其他标识符和表示相关联的值.这与标识符→表示映射不同.只要两者都由相同的资源相关联,服务器就可以将它想要的任何标识符映射到任何表示.
开发人员可以通过考虑"用户"和"帖子"之类的事物来提出合理描述业务的资源定义.
如果我真的关心完美的HATEOAS,我可以在/foo表示中的某处放置一个超链接/foo/members,并且该表示只包含指向每个支持的成员组合的超链接.
从URL 的定义:
查询组件包含非分层数据,该数据与路径组件中的数据一起用于标识URI方案和命名权限(如果有)范围内的资源.
所以/foo?sections=a,b,d并且/foo?sections=b是不同的标识符.但是,它们可以在映射到不同表示的同一资源中关联.
HTTP的404代码意味着服务器找不到映射URL的任何内容,而不是URL没有与任何资源相关联.
任何浏览器或缓存都不会出现斜杠或连字符问题.
实际上,这取决于资源的功能。例如,如果资源表示实体:
/customers/5
这里的“ 5”代表客户的ID
响应:
{
"id": 5,
"name": "John",
"surename": "Doe",
"marital_status": "single",
"sex": "male",
...
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我们仔细检查一下,每个json属性实际上代表客户资源实例上记录的一个字段。假设消费者希望得到部分响应,即部分字段。我们可以将其视为消费者希望通过请求选择各种字段的功能,这对他来说很有趣,但没有更多(为了节省流量或性能,如果部分字段难以计算) 。
我认为在这种情况下,最易读和正确的API是(例如,仅获取name和surename)
/customers/5?fields=name,surename
Run Code Online (Sandbox Code Playgroud)
响应:
{
"name": "John",
"surename": "Doe"
}
Run Code Online (Sandbox Code Playgroud)
fields=id,name或fields=name,id),尽管响应相同,但这些响应将分别缓存。
排列!)。 | 归档时间: |
|
| 查看次数: |
11965 次 |
| 最近记录: |