ReSTful API 主要由其他系统使用,这就是我将分页数据放在响应标头中的原因。但是,某些 API 使用者可能无法直接访问响应标头,或者可能正在您的 API 上构建 UX,因此提供一种(按需)检索 JSON 响应中的元数据的方法是一个优势。
我相信你的实现应该包括机器可读的元数据作为默认值,并在请求时包括人类可读的元数据。如果您愿意,可以随每个请求返回人类可读的元数据,或者最好通过查询参数按需返回,例如include=metadata
or 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"
}
]
}
对于机器可读的元数据,我会在响应中添加链接头:
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
(链接标头值应为 urlencoded)
...total-count
如果您选择,可能还有自定义响应标头:
total-count: 521
以人为中心的元数据中显示的其他分页数据对于以机器为中心的元数据可能是多余的,因为链接标题让我知道我在哪个页面以及每页的数量,并且我可以快速检索数组中的记录数. 因此,我可能只会为总数创建一个标题。您可以随时改变主意并添加更多元数据。
顺便说一句,您可能会注意到我/index
从您的 URI 中删除了。一个普遍接受的约定是让您的 ReST 端点公开集合。最后/index
有点混乱。
这些只是我在使用/创建 API 时喜欢的一些东西。希望有帮助!