背景
我们正在构建一个应该以 JSON 形式返回数据对象的 Restful API。在大多数情况下,只返回数据对象就可以了,但在某些情况下,f.ex。分页或验证,我们需要在响应中添加一些元数据。
我们目前所拥有的
我们已经像这个例子一样包装了所有的 json 响应:
{
"metadata" :{
"status": 200|500,
"msg": "Some message here",
"next": "http://api.domain.com/users/10/20"
...
},
"data" :{
"id": 1001,
"name": "Bob"
}
}
优点
- 我们可以在回复中添加有用的元数据
缺点
- 在大多数情况下我们不需要元数据字段,它增加了 json 格式的复杂性
- 由于它不再是数据对象,而更像是一个封装的响应,我们不能在不提取数据对象的情况下立即在 f.ex Backbone 中使用响应。
问题
将元数据添加到 json 响应的最佳做法是什么?
更新
到目前为止,我从以下答案中得到了什么:
- 删除
metadata.status
并返回 http 响应代码 而是 http 协议(protocol) (200, 500 ...) - 将错误消息添加到 http 500 响应的正文中
- 对于分页,我很自然地需要一些元数据来说明分页结构以及嵌套在该结构中的数据
- 可以在http header(X-something)中添加少量元数据
最佳答案
您可以通过多种方式在 RESTful API 中传递元数据:
- Http 状态码
- 标题
- 响应正文
对于 metadata.status,使用 Http 状态码,就是这样! 如果元数据是指整个响应,您可以将其添加为标题字段。 如果元数据仅涉及响应的一部分,则必须将元数据作为对象的一部分嵌入。不要将整个响应包装在一个人造信封中,并将包装器拆分为数据和元数据。
最后,在您的 API 中保持一致与您所做的选择。
一个很好的例子是使用分页对整个集合进行 GET。获取/项目 您可以在自定义标题中返回集合大小和当前页面。以及标准链接头中的分页链接:
Link: <https://api.mydomain.com/v1/items?limit=25&offset=25>; rel=next
这种方法的问题是当您需要在响应中添加引用特定元素的元数据时。在这种情况下,只需将其嵌入对象本身。并采用一致的方法...始终将所有元数据添加到响应中。所以回到 GET/items,假设每个项目都创建并更新了元数据:
{
items:[
{
"id":"w67e87898dnkwu4752igd",
"message" : "some content",
"_created": "2014-02-14T10:07:39.574Z",
"_updated": "2014-02-14T10:07:39.574Z"
},
......
{
"id":"asjdfiu3748hiuqdh",
"message" : "some other content",
"_created": "2014-02-14T10:07:39.574Z",
"_updated": "2014-02-14T10:07:39.574Z"
}
],
"_total" :133,
"_links" :[
{
"next" :{
href : "https://api.mydomain.com/v1/items?limit=25&offset=25"
}
]
}
请注意,收集响应是一种特殊情况。如果将元数据添加到集合中,则该集合不能再作为数组返回,它必须是包含数组的对象。为什么是对象?因为你想添加一些元数据属性。
与单个项目中的元数据进行比较。没有任何东西可以包裹实体。您只需为资源添加一些属性。
一种约定是区分控制字段或元数据字段。您可以在这些字段前加上下划线。
关于java - 将元数据添加到 RESTful JSON 响应的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8294265/