REST API 客户端指定响应详细信息的好方法?
Good method for a REST API client to specify the desired amount of detail of the response?
我正在设计一个 REST API,多个客户端将使用它来查询数据存储库。我预计这些客户对 amount/level 响应细节会有不同的需求。
假设我可以查询 collection 本书。一本书可能有很多属性(比任何一个客户可能感兴趣的都多),甚至可能有子资源,并且客户可能会请求大量的书,导致响应 body 比需要的更大。
因此我正在研究优化响应大小的方法。这个想法是为 API 客户端提供一些方法来指定响应中应包含多少详细信息。
我很想知道这个问题以前是如何解决的;哪个机制在实践中运作良好,哪个没有,哪个API设计特别RESTful,哪个不是,等等。
我可以想到客户如何为响应指定所需详细程度的几种方法:
使用 GET
或 HEAD
HTTP 方法/动词。前者会 return 所有细节,前者只会是一个子集。
这种方法只能让我们区分两个层次的细节,所以用途有限。
有一个 查询字符串参数 指定(按名称)哪个 properties/attributes 应该在响应中 returned。例如:
GET /books?include=title,author,publisher,...,preview
这提供了几乎无限的灵活性,但这种灵活性可能很难实际实现和处理(在客户端和服务器端)。
使用不同的媒体类型(每个细节级别一种不同的媒体类型),通过Accept:
header选择。
我真的不想走那条路。我不确定媒体类型是否适合此目的,而且世界可能不需要更多的自定义媒体类型。
使用profile
关系/媒体类型参数。这似乎好一点(不需要额外的媒体类型),但我仍然不确定媒体类型是否是选择响应的 "what"(内容)的正确方法。它们似乎更适合仅指定响应的 "how"(格式)。
对于书 collections (/books?publishedIn=1980s
),所有可用数据中只有一小部分是 returned,最重要的是 href
对于可以查询的每本书以获取有关单本书的完整数据。
这种方法至少有两个问题:
除了 href
链接之外,collection 响应中还包含哪些属性?理想情况下,有足够的附加数据来满足大多数客户;否则...
客户将不得不执行大量额外的查询(每本书一个)来收集他们需要的所有数据。
可能有更多的策略来选择所需的详细程度。我有兴趣了解什么在实践中行之有效,又不会严重损害 RESTfulness。
我认为这主要取决于您想为 API 客户提供多少灵活性。
如果您知道数据的不同用途,您可能想要定义一些您的 API 可以 return 的可用格式。
例如,使用这个结构:
GET /books (with a default format if nothing is specified)
GET /books/minimal
GET /books/full
GET /books/otherformat
请注意,如果您不想复制端点,也可以使用此 URL 结构:
GET /books?format=minimal
但是,无论哪种情况,这都会迫使您准确了解客户在任何给定时间需要或想要的数据。
我不会依赖媒体类型,因为与使用 REST 的其他更标准的方式相比,这可能会让用户更加困惑 APIs。
[编辑]
此外,如果您决定将整个 fiends 列表指定给 return 并发现 GET 请求不够,您可以参考此 post 以使用 POST 请求
我正在设计一个 REST API,多个客户端将使用它来查询数据存储库。我预计这些客户对 amount/level 响应细节会有不同的需求。
假设我可以查询 collection 本书。一本书可能有很多属性(比任何一个客户可能感兴趣的都多),甚至可能有子资源,并且客户可能会请求大量的书,导致响应 body 比需要的更大。
因此我正在研究优化响应大小的方法。这个想法是为 API 客户端提供一些方法来指定响应中应包含多少详细信息。
我很想知道这个问题以前是如何解决的;哪个机制在实践中运作良好,哪个没有,哪个API设计特别RESTful,哪个不是,等等。
我可以想到客户如何为响应指定所需详细程度的几种方法:
使用
GET
或HEAD
HTTP 方法/动词。前者会 return 所有细节,前者只会是一个子集。这种方法只能让我们区分两个层次的细节,所以用途有限。
有一个 查询字符串参数 指定(按名称)哪个 properties/attributes 应该在响应中 returned。例如:
GET /books?include=title,author,publisher,...,preview
这提供了几乎无限的灵活性,但这种灵活性可能很难实际实现和处理(在客户端和服务器端)。
使用不同的媒体类型(每个细节级别一种不同的媒体类型),通过
Accept:
header选择。我真的不想走那条路。我不确定媒体类型是否适合此目的,而且世界可能不需要更多的自定义媒体类型。
使用
profile
关系/媒体类型参数。这似乎好一点(不需要额外的媒体类型),但我仍然不确定媒体类型是否是选择响应的 "what"(内容)的正确方法。它们似乎更适合仅指定响应的 "how"(格式)。对于书 collections (
/books?publishedIn=1980s
),所有可用数据中只有一小部分是 returned,最重要的是href
对于可以查询的每本书以获取有关单本书的完整数据。这种方法至少有两个问题:
除了
href
链接之外,collection 响应中还包含哪些属性?理想情况下,有足够的附加数据来满足大多数客户;否则...客户将不得不执行大量额外的查询(每本书一个)来收集他们需要的所有数据。
可能有更多的策略来选择所需的详细程度。我有兴趣了解什么在实践中行之有效,又不会严重损害 RESTfulness。
我认为这主要取决于您想为 API 客户提供多少灵活性。
如果您知道数据的不同用途,您可能想要定义一些您的 API 可以 return 的可用格式。
例如,使用这个结构:
GET /books (with a default format if nothing is specified)
GET /books/minimal
GET /books/full
GET /books/otherformat
请注意,如果您不想复制端点,也可以使用此 URL 结构:
GET /books?format=minimal
但是,无论哪种情况,这都会迫使您准确了解客户在任何给定时间需要或想要的数据。
我不会依赖媒体类型,因为与使用 REST 的其他更标准的方式相比,这可能会让用户更加困惑 APIs。
[编辑]
此外,如果您决定将整个 fiends 列表指定给 return 并发现 GET 请求不够,您可以参考此 post 以使用 POST 请求