在 REST 调用中使用 URI 作为参数值的最佳实践

Posted

技术标签:

【中文标题】在 REST 调用中使用 URI 作为参数值的最佳实践【英文标题】:Best practices on using URIs as parameter value in REST calls 【发布时间】:2011-02-18 15:01:58 【问题描述】:

我正在设计一个 REST API,其中一些资源可以通过查询参数进行过滤。在某些情况下,这些过滤器值将是来自同一 REST API 的资源。这使得 URI 变得冗长且难以阅读。虽然这本身并没有太大的问题,因为 URI 旨在以编程方式创建和操作,但它会带来一些痛苦的调试。我正在考虑允许将 URI 的快捷方式用作过滤器值,我想知道根据 REST 架构是否允许这样做,是否有任何最佳实践。

例如:

我有一个资源可以让我获得 Java 类。那么下面的请求会给我所有的 Java 类:

GET http://example.org/api/v1/class

假设我想要Collection Java 类的所有子类,那么我将使用以下请求:

GET http://example.org/api/v1/class?has-supertype=http://example.org/api/v1/class/collection

该请求将返回我VectorArrayListCollection Java 类的所有其他子类。

不过,这个 URI 很长。我已经可以通过允许hs 作为has-supertype 的别名来缩短它。这会给我:

GET http://example.org/api/v1/class?hs=http://example.org/api/v1/class/collection

另一种允许使用较短 URI 的方法是允许 URI 前缀使用别名。例如,我可以将class 定义为URI 前缀http://example.org/api/v1/class/ 的别名。这会给我以下可能性:

GET http://example.org/api/v1/class?hs=class:collection

另一种可能性是完全删除类别名并始终在参数值前加上http://example.org/api/v1/class/,因为这是我唯一支持的。这会将Collection 的所有子类型的请求变成:

GET http://example.org/api/v1/class?hs=collection

原始请求 URI 的这些“简化”是否仍然符合 REST 架构的原则?还是我只是走得太远了?

附录: URI 中可能同时存在多个过滤器。可以作为不同的参数,也可以作为单个参数的值列表。 按照“实现接口 X 和/或接口 Y 的所有类”或“实现接口 X 并在包 ABC 中的所有类”的思路思考(其中包也可以寻址到像 http://example.org/api/v1/packages/a/b/c 这样的 URI)

【问题讨论】:

添加了问题的附录。 【参考方案1】:

我会去做:

GET http://example.org/api/v1/class/java.util.Collection/subclasses

返回指向 RESTful API 中其他条目的链接列表,每个直接子类都有一个。我还会将该信息作为返回的描述符的一部分提供:

GET http://example.org/api/v1/class/java.util.Collection

(这也将包括指向前面特定查询的链接。)

【讨论】:

我在问题中添加了附录。 @S.Lott 你能解释一下你避免使用查询字符串的原因吗?我的印象是这对于 REST API 来说很好。 @dafmetal:据我所知,如果 RESTful 接口可以提供帮助,它们并不会真正用于如此复杂的事情。在他们做不到的地方,他们会处理一个可怕的foo?query=bar 事件,该事件会返回一个指向满足查询的资源的链接列表。

以上是关于在 REST 调用中使用 URI 作为参数值的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

超长 URI 的 REST 最佳实践

具有匿名/识别访问的 REST API 的最佳 URI 模式是啥?

REST API 最佳实践:查询字符串中的参数与请求正文中的参数

通过更改android中的参数来重复调用rest api的最佳方法是啥

SoapUI,Rest:如何避免在soapui中的REST请求URI中进行参数编码?

URI 和响应中参数的 API 最佳实践