我猜这是一个概念而非技术问题。假设我有一个REST API来处理庞大的租车车队。
API是以非常标准和连贯的(即使是有争议的)方式围绕业务实体/资源建模的:
/cars/1234
- 有关某辆车的详细数据/clients/5678
- 有关某个客户的详细数据/cars
- 汽车列表及其URI /clients
- 客户列表然而,车队很庞大,所有车辆的清单都没用。我宁愿过滤它,例如:
GET /cars?type=minivan
为了正确使用“type
”参数,我应该有一个有效值列表,例如“minivan”,“convertible”,“station-wagon”,“hatchback”,“sedan”等。好吧,那里没有那么多种车,但我们假设这个列表对于API的Swagger定义中的枚举来说太大了。
那么...... REST API为查询参数提供有效值列表的最一致和最自然的方式是什么?
作为/cars/types
等附属资源?这会打破/cars/{id}
网址格式,不是吗?
作为/tables/cars/types
等单独的资源?这会打破商业模式本身主要资源的一致性,对吧?
作为OPTIONS /cars
回复正文的一部分?对我来说,它看起来像是“最完美”的方式,但是我的一些同事不同意,OPTIONS似乎很少用于那样的事情。
也许是对GET /cars?&metadata=values
或类似内容的回应的一部分?这里的“值”看起来与返回的数据在语义上更相关,而不是查询参数,不是吗?
还有别的吗?
我在Google搜索并搜索了有关此特定主题的一些建议,但我找不到任何可以帮助我做出这样决定的论据......
谢谢!
Fabricio Rocha
Brasilia,Brasil
答案 0 :(得分:2)
“一个好的REST API就像一个丑陋的网站” - Rickard Öberg
那你怎么在网站上做呢?好吧,你可能有一个链接转到表单,表单将有一个列表控件/单选按钮,每个选项都有语义提示,期望用户从可用选项中选择一个值,并且用户代理会在提交表单时将该值编码到GET请求的URL中。
所以在REST中,你做同样的事情。在初始响应中,您将包含指向“表单”资源的链接;当用户代理获取表单资源时,您将返回表单的超媒体表示,并在其中编码可用选项,并且在提交表单时,您的资源会从标识符的查询部分中选择客户端选项。
但是你可能没有做REST:它是一个巨大的PITA,REST架构约束的好处可能不会在你的上下文中得到回报。因此,您可能只是寻找合理的标识符拼写,以便返回带有选项列表的消息。
作为/ cars / types这样的从属资源?这会破坏/ cars / {id}网址格式,不是吗?
假设您的路由实现可以处理歧义,那是一个不错的选择。您可以考虑是否只有一个列表,或不同上下文的不同列表,以及如何处理它。
作为单独的资源,例如/ tables / cars / types?这会打破商业模式本身主要资源的一致性,对吧?
还记得OO编程和封装吗?将API与底层数据模型分离是一件好事。
那就是说,我个人并不喜欢“桌子”作为你的等级中的一个元素。如果您想要朝着这个方向前进,我建议/dimensions
- 如果您正在设计data warehouse
作为OPTIONS /汽车响应机构的一部分?对我来说,它看起来像是“RESTfullest”的方式,但是我的一些同事不同意,OPTIONS似乎很少用于那样的事情。
糟糕! RFC 7231表明这是一个非常令人困惑的想法。
OPTIONS方法在原始服务器或介入中介处请求有关目标资源可用的通信选项的信息。
(重点补充)。在为Web编写API时,您应始终牢记客户端请求可能会通过您无法控制的中介;你在这种情况下提供良好体验的能力取决于不偏离统一界面而混淆中间人。
也许作为对GET /汽车的回应的一部分?& metadata = values或类似的东西?
在大多数情况下,机器对任何拼写都很舒服。 URI设计指南通常关注人类受众。我认为特定的拼写会让您的人类消费者感到困惑,尤其是/cars?...
否则会识别出作为搜索结果的资源。
还有别的吗?我仍然觉得人们期望在汽车下发现的是......一堆汽车(他们的代表,我的意思),而不是他们中的一系列价值......
所以让我们稍微改变一下你的问题
REST API最一致和最自然的方式是记录查询参数的有效值列表?
如果网络真的有一件好事,那就是记录事情。选择几乎所有记录良好的Web API,并仔细关注您在哪里阅读有关端点的信息 - 这将为您提供一些好主意。
例如,您可以查看StackExchange API
https://api.stackexchange.com/docs/questions
告诉您需要了解的有关资源系列资源的所有内容
https://api.stackexchange.com/2.2/questions
类型,不出所料,记录如下:
https://api.stackexchange.com/docs/types/flag-option
如果你想要表现性感,可以使用Accept-Type协商重定向到人类可读文档或机器可读文档。
答案 1 :(得分:1)
我处于类似的情况但我有大量的字段,每个字段都有大量可能的值,在某些情况下,值来自层次结构,所以我的字段是一个字符串数组。 (借用你的例子:你可能想要记录制造汽车的工厂,而不是记录这些按照大陆,国家和州组织的一维清单。)
我想我会实现一个/ taxonomies资源来向用户提供所有数据。我看到WordPress使用了类似的方案(http://v2.wp-api.org/reference/taxonomies/),尽管我还没有仔细研究过它。