RESTful API设计:查询参数的列表值选项

RESTful API设计:查询参数的列表值选项,rest,api-design,httpverbs,Rest,Api Design,Httpverbs,假设您正在构建一个API,该API在 [GET] /resources => [ {.. id: 1, foo: "A" ..}, {.. id: 2, foo: "B" ..}, {.. id: 3, foo: "A" ..} ] 可以使用查询参数进行筛选: [GET] /resources&foo=A => [ {.. id: 1, foo: "A" ..}, {.. id: 3, foo: "A" ..} ] 到目前为止,一切顺利 现在要求您创建一个端点,该端

假设您正在构建一个API,该API在

[GET] /resources
=> 
[
 {.. id: 1, foo: "A" ..}, {.. id: 2, foo: "B" ..}, {.. id: 3, foo: "A" ..}
]
可以使用
查询参数进行筛选

[GET] /resources&foo=A
=>
[
 {.. id: 1, foo: "A" ..}, {.. id: 3, foo: "A" ..}
]
到目前为止,一切顺利

现在要求您创建一个端点,该端点返回
foo
的可用值
您希望哪个端点返回可用于筛选资源的选项?


我的建议是使用HTTP方法:

此方法允许客户端 确定与项目相关的选项和/或要求 资源或服务器的功能,而不意味着 资源行动


但是我恐怕这个HTTP方法是为描述数据域而设计的

准确地说,正如您正确地指出的那样,选项方法保留用于通信选项,而不是内容,并且用于CORS验证

我会使用以下其中一种:

  • 获取/资源类型?字段=foo
  • 获取/资源/类型?字段=foo
您可以用在您的案例中更有意义的内容替换“类型”,如“allowedValues”、“enum”等


通常,根据我的经验,在REST中,可过滤的值是预先知道的,或者您有一个没有预定值的免费搜索字段。

您实际的问题是如何教客户如何选择某个资源。如果您仔细观察Web和HTML,尤其是HTML,您可能会发现HTML使用表单来向浏览器(=客户端)传授服务器期望从客户端输入的内容,以及发送请求之前可以采取的选择

包含有关可以在表单中使用的各个元素的语法和语义的描述。通过这种方式,服务器可以发送option元素,让客户机在两个或多个选项之间进行选择。目前,有几个草案试图将这个概念转换为HTML以外的其他表示格式,但据我所知,没有一个草案足够重要,或者已经得到广泛接受。其中有一些基于JSON的,比如,和

REST API应该将其几乎所有的描述性工作用于定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有标准媒体类型定义扩展关系名称和/或支持超文本的标记。描述在感兴趣的URI上使用什么方法的任何工作都应该完全在媒体类型的处理规则范围内定义(在大多数情况下,已经由现有媒体类型定义)

application/json
对于真正的REST客户机来说不是一种很好的表示格式,因为它缺乏语义来描述类表单表示可能具有的各个元素,以及该表示的使用者应该如何正确处理信息的处理规则。在这里,上述媒体类型之一肯定是有益的。问题不应该是选择哪一个,而是你想支持多少。您支持的格式越多,任意客户端就越有可能与您的系统交互

客户机和服务器应始终使用内容类型协商来商定双方都能理解的表示格式,以便交换数据。这减少了互操作性问题,因为两个客户端都知道如何处理和解释商定的媒体类型。如果没有可用的通用表示格式,或者客户端发送了服务器不熟悉的表示,服务器将通知客户端其无法向客户端提供内容

REST的全部目的是允许服务器在未来自由发展,而不必担心破坏客户端。这在有许多不同客户机和API的领域尤其有益,这些客户机和API不在您的控制之下。EDI将是这样一个领域,可以为您提供更好的可视化效果。在这里,许多ERP系统和应用程序必须交换业务文档,如订单和发票。有两种标准化的表示格式,如EDIFACT,尽管使用了大量的自定义格式,这使整个区域非常有趣。基本上,您不希望为与之交互的每个ERP系统创建定制的客户机(或服务器),而是平等地处理每个交换的消息

对于前端到后端的通信,尽管您并不真正需要一个完全充实的REST体系结构,因为这可能会给您带来比它提供的任何好处都更多的负担。REST中的事实是,客户端和服务器都必须仔细设计,以避免耦合。如果只有一个参与者试图忽略部署到位的约束之一,则可能存在耦合,这会阻止服务器在未来添加新功能,而不会影响客户端或客户端保持与服务交互的能力


因此,如果你想教客户他们在某些资源上有什么选择,那么就在Web上进行定向,并使用能够表达这种能力的媒体类型,以便客户可以利用它。

作为客户机,我希望服务器提供一个我只需调用的URI。作为一个客户端,我不在乎如何设计URI,我只想调用它。给我一些其他提示,让我决定是否调用该URI。这基本上就是20多年来Web在HTML中使用链接和表单所做的事情successfully@LawrenceCherone
A
不是键,它只是一个有“枚举”感觉的字段。编辑问题,以便使它清晰的A - 1是好的,但更具建设性,如果解释为什么你认为它是无用的社区,我投票关闭这个问题作为主题,因为它属于软件工程谢谢!你知道这方面有什么惯例吗?正如罗曼·沃特纳评论的那样,就我所知,这确实是一个品味问题,没有具体的惯例
[OPTIONS] /resources
=> 
{
  foo: ["A","B"]
}