我想在我的RESTful API中支持分页.
我的API方法应返回产品的JSON列表/products/index.但是,可能存在数千种产品,我想通过它们进行分页,因此我的请求看起来应该是这样的:
/products/index?page_number=5&page_size=20
Run Code Online (Sandbox Code Playgroud)
但是我的JSON响应需要看起来像什么?API消费者通常会在响应中期望分页元数据吗?或者只是一系列必要的产品?为什么?
看起来Twitter的API包含元数据:https://dev.twitter.com/docs/api/1/get/lists/members(请参阅示例请求).
使用元数据:
{
"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"
}
]
}
Run Code Online (Sandbox Code Playgroud)
只是一系列产品(没有元数据):
[
{
"id": 1,
"name": "Widget #1"
},
{
"id": 2,
"name": "Widget #2"
},
{
"id": 3,
"name": "Widget #3"
}
]
Run Code Online (Sandbox Code Playgroud)
cod*_*ion 95
ReSTful API主要由其他系统使用,这就是我将分页数据放在响应头中的原因.但是,某些API使用者可能无法直接访问响应标头,或者可能正在构建基于API的UX,因此提供一种方法来检索(按需)JSON响应中的元数据是一个优点.
我相信您的实现应该包括默认的机器可读元数据,以及请求时的人类可读元数据.如果您愿意,可以随每个请求返回人类可读的元数据,或者最好通过查询参数(例如include=metadata或)按需返回include_metadata=true.
在您的特定场景中,我将包含每个产品的URI和记录.这使API使用者可以轻松创建指向各个产品的链接.我还会根据我的分页请求的限制设置一些合理的期望.实现和记录页面大小的默认设置是可以接受的做法.例如,GitHub的API将默认页面大小设置为30条记录,最多为100条,另外还设置了查询API的速率限制.如果您的API具有默认页面大小,则查询字符串只能指定页面索引.
在人类可读的场景中,导航到时/products?page=5&per_page=20&include=metadata,响应可能是:
{
"_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"
}
]
}
Run Code Online (Sandbox Code Playgroud)
对于机器可读的元数据,我会在响应中添加链接头:
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
Run Code Online (Sandbox Code Playgroud)
(链接头值应该是urlencoded)
... total-count如果您这样选择,可能还有自定义响应头:
total-count: 521
Run Code Online (Sandbox Code Playgroud)
在以人为中心的元数据中显示的其他分页数据对于以机器为中心的元数据可能是多余的,因为链接标题让我知道我在哪个页面和每页的数量,并且我可以快速检索数组中的记录数量.因此,我可能只会为总计数创建一个标题.您可以随时改变主意并添加更多元数据.
另外,您可能会注意到我/index从您的URI中删除了.一个普遍接受的约定是让您的ReST端点公开集合.有/index在年底muddies是略有上升.
在使用/创建API时,这些只是我喜欢的一些内容.希望有所帮助!
小智 29
作为编写了几个用于使用REST服务的库的人,让我向您提供客户视角,了解为什么我认为将结果包装在元数据中是最佳选择:
并提出建议:与Twitter API一样,您应该使用直接索引/光标替换page_number.原因是,API允许客户端为每个请求设置页面大小.返回的page_number是客户端到目前为止请求的页数,还是给出最后一次使用的page_size的页面数(几乎可以肯定是后者,但为什么不完全避免这种歧义)?
adn*_*ili 12
我建议为它添加标题.将元数据移动到标题有助于摆脱类似的包络result,data或者records响应主体仅包含我们需要的数据.如果您也生成分页链接,则可以使用链接标题.
HTTP/1.1 200
Pagination-Count: 100
Pagination-Page: 5
Pagination-Limit: 20
Content-Type: application/json
[
{
"id": 10,
"name": "shirt",
"color": "red",
"price": "$23"
},
{
"id": 11,
"name": "shirt",
"color": "blue",
"price": "$25"
}
]
Run Code Online (Sandbox Code Playgroud)
有关详情,请参阅:
https://github.com/adnan-kamili/rest-api-response-format
对于招摇文件:
https://github.com/adnan-kamili/swagger-response-template
| 归档时间: |
|
| 查看次数: |
80403 次 |
| 最近记录: |