来自 RESTful API 的分页响应负载 [英] Pagination response payload from a RESTful API

查看:30
本文介绍了来自 RESTful API 的分页响应负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的 RESTful API 中支持分页.

我的 API 方法应该通过 /products/index 返回产品的 JSON 列表.但是,可能有数以千计的产品,我想浏览它们,所以我的请求应该是这样的:

/products/index?page_number=5&page_size=20

但是我的 JSON 响应需要是什么样的?API 消费者通常会期望响应中的分页元数据吗?还是只需要一系列产品?为什么?

看起来 Twitter 的 API 包含元数据:https://dev.twitter.com/docs/api/1/get/lists/members(请参阅示例请求).

使用元数据:

<代码>{"page_number": 5,页面大小":20,total_record_count":521,记录": [{身份证":1,"name": "小部件 #1"},{身份证":2,"name": "小部件 #2"},{身份证":3,"name": "小部件 #3"}]}

只是一组产品(没有元数据):

<预><代码>[{身份证":1,"name": "小部件 #1"},{身份证":2,"name": "小部件 #2"},{身份证":3,"name": "小部件 #3"}]

解决方案

ReSTful API 主要由其他系统使用,这就是我将分页数据放在响应标头中的原因.但是,某些 API 使用者可能无法直接访问响应标头,或者可能正在通过您的 API 构建 UX,因此提供一种在 JSON 响应中检索(按需)元数据的方法是一个加分项.

我相信您的实现应该包含机器可读的元数据作为默认值,并在需要时包含人类可读的元数据.如果您愿意,或者最好是按需通过查询参数(例如 include=metadatainclude_metadata=true),可以随每个请求返回人类可读的元数据.

在您的特定场景中,我会在记录中包含每个产品的 URI.这使得 API 使用者可以轻松地创建指向各个产品的链接.我还会根据我的分页请求的限制设置一些合理的期望.实施和记录页面大小的默认设置是一种可接受的做法.例如,GitHub 的 API 将默认页面大小设置为 30 条记录,最多 100 条,加上对可以查询 API 的次数设置速率限制.如果您的 API 具有默认页面大小,则查询字符串可以指定页面索引.

在人类可读的场景中,当导航到 /products?page=5&per_page=20&include=metadata 时,响应可能是:

<代码>{_元数据":{页面":5,每页":20,page_count":20,total_count":521,链接":[{"self": "/products?page=5&per_page=20"},{"first": "/products?page=0&per_page=20"},{"previous": "/products?page=4&per_page=20"},{"next": "/products?page=6&per_page=20"},{"last": "/products?page=26&per_page=20"},]},记录": [{身份证":1,"name": "小部件 #1","uri": "/products/1"},{身份证":2,"name": "小部件 #2","uri": "/products/2"},{身份证":3,"name": "小部件 #3","uri": "/products/3"}]}

对于机器可读的元数据,我会在响应中添加链接标头:

链接:</products?page=5&perPage=20>;rel=self,</products?page=0&perPage=20>;rel=first,</products?page=4&perPage=20>;rel=previous,</products?page=6&perPage=20>;rel=next,</products?page=26&perPage=20>rel=last

(链接标头值应该是 urlencoded)

...以及可能的自定义 total-count 响应标头,如果您选择:

总数:521

在以人为中心的元数据中显示的其他分页数据对于以机器为中心的元数据可能是多余的,因为链接标题让我知道我在哪个页面以及每页的数量,我可以快速检索记录数量在数组中.因此,我可能只会为总计数创建一个标题.您可以随时改变主意并添加更多元数据.

顺便说一句,您可能会注意到我从您的 URI 中删除了 /index.普遍接受的约定是让您的 ReST 端点公开集合./index 结尾稍微有点混乱.

这些只是我在使用/创建 API 时喜欢的一些东西.希望有帮助!

I want to support pagination in my RESTful API.

My API method should return a JSON list of product via /products/index. However, there are potentially thousands of products, and I want to page through them, so my request should look something like this:

/products/index?page_number=5&page_size=20

But what does my JSON response need to look like? Would API consumers typically expect pagination meta data in the response? Or is only an array of products necessary? Why?

It looks like Twitter's API includes meta data: https://dev.twitter.com/docs/api/1/get/lists/members (see Example Request).

With meta data:

{
  "page_number": 5,
  "page_size": 20,
  "total_record_count": 521,
  "records": [
    {
      "id": 1,
      "name": "Widget #1"
    },
    {
      "id": 2,
      "name": "Widget #2"
    },
    {
      "id": 3,
      "name": "Widget #3"
    }
  ]
}

Just an array of products (no meta data):

[
  {
    "id": 1,
    "name": "Widget #1"
  },
  {
    "id": 2,
    "name": "Widget #2"
  },
  {
    "id": 3,
    "name": "Widget #3"
  }
]

解决方案

ReSTful APIs are consumed primarily by other systems, which is why I put paging data in the response headers. However, some API consumers may not have direct access to the response headers, or may be building a UX over your API, so providing a way to retrieve (on demand) the metadata in the JSON response is a plus.

I believe your implementation should include machine-readable metadata as a default, and human-readable metadata when requested. The human-readable metadata could be returned with every request if you like or, preferably, on-demand via a query parameter, such as include=metadata or include_metadata=true.

In your particular scenario, I would include the URI for each product with the record. This makes it easy for the API consumer to create links to the individual products. I would also set some reasonable expectations as per the limits of my paging requests. Implementing and documenting default settings for page size is an acceptable practice. For example, GitHub's API sets the default page size to 30 records with a maximum of 100, plus sets a rate limit on the number of times you can query the API. If your API has a default page size, then the query string can just specify the page index.

In the human-readable scenario, when navigating to /products?page=5&per_page=20&include=metadata, the response could be:

{
  "_metadata": 
  {
      "page": 5,
      "per_page": 20,
      "page_count": 20,
      "total_count": 521,
      "Links": [
        {"self": "/products?page=5&per_page=20"},
        {"first": "/products?page=0&per_page=20"},
        {"previous": "/products?page=4&per_page=20"},
        {"next": "/products?page=6&per_page=20"},
        {"last": "/products?page=26&per_page=20"},
      ]
  },
  "records": [
    {
      "id": 1,
      "name": "Widget #1",
      "uri": "/products/1"
    },
    {
      "id": 2,
      "name": "Widget #2",
      "uri": "/products/2"
    },
    {
      "id": 3,
      "name": "Widget #3",
      "uri": "/products/3"
    }
  ]
}

For machine-readable metadata, I would add Link headers to the response:

Link: </products?page=5&perPage=20>;rel=self,</products?page=0&perPage=20>;rel=first,</products?page=4&perPage=20>;rel=previous,</products?page=6&perPage=20>;rel=next,</products?page=26&perPage=20>;rel=last

(the Link header value should be urlencoded)

...and possibly a custom total-count response header, if you so choose:

total-count: 521

The other paging data revealed in the human-centric metadata might be superfluous for machine-centric metadata, as the link headers let me know which page I am on and the number per page, and I can quickly retrieve the number of records in the array. Therefore, I would probably only create a header for the total count. You can always change your mind later and add more metadata.

As an aside, you may notice I removed /index from your URI. A generally accepted convention is to have your ReST endpoint expose collections. Having /index at the end muddies that up slightly.

These are just a few things I like to have when consuming/creating an API. Hope that helps!

这篇关于来自 RESTful API 的分页响应负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆