是否存在从API构建JSON响应的标准或最佳实践?显然,每个应用程序的数据都是不同的,所以我不太关心,而是“响应样板”,如果你愿意的话。我的意思是:
成功的请求:
{
"success": true,
"payload": {
/* Application-specific data would go here. */
}
}
失败的请求:
{
"success": false,
"payload": {
/* Application-specific data would go here. */
},
"error": {
"code": 123,
"message": "An error occurred!"
}
}
我不会傲慢地宣称这是一个标准,所以我会使用“我更喜欢”的形式。
我更喜欢简洁的响应(当请求/articles列表时,我需要一个JSON文章数组)。
在我的设计中,我使用HTTP进行状态报告,200只返回有效负载。
400返回请求出错的消息:
{"message" : "Missing parameter: 'param'"}
如果模型/控制器/URI不存在,则返回404
如果我这边的处理出现错误,我会返回501并返回消息:
{"message" : "Could not connect to data store."}
从我所看到的情况来看,相当多的REST框架都是这样的。
理论基础:
JSON应该是一种有效载荷格式,而不是会话协议。冗长的会话式有效负载的整个概念来自XML/SOAP世界,以及导致这些臃肿设计的各种错误选择。在我们意识到所有这些都是一个令人头疼的问题之后,REST/JSON的全部目的就是KISS,并遵守HTTP。我不认为JSend中有任何远程标准,尤其是其中更冗长的部分。XHR将对HTTP响应做出反应,如果您对AJAX使用jQuery(像大多数人一样),您可以使用try/catch和done()/fail()回调来捕获错误。我看不出用JSON封装状态报告有多有用。
JSON的关键在于它是完全动态和灵活的。你可以随心所欲地使用它,因为它只是一组序列化的JavaScript对象和数组,植根于一个节点。
rootnode的类型取决于您,它包含的内容取决于您、是否随响应一起发送元数据取决于您以及是否将mime类型设置为application/json或将其保留为text/plain取决于您(只要您知道如何处理边缘情况)。
构建您喜欢的轻量级模式。就我个人而言,我发现分析跟踪、mp3/ogg服务、图片库服务、在线游戏的短信和网络包、博客帖子和博客评论在发送内容、接收内容以及如何消费方面都有着非常不同的要求。
所以,在完成所有这些工作时,我最不想做的就是让每一个都符合相同的样板标准,该标准基于XML2.0或类似的标准。
也就是说,使用对你有意义且经过深思熟虑的模式有很多值得说的地方。只需阅读一些API响应,注意你喜欢的,批评你不喜欢的,写下这些批评,并理解它们为什么会让你感到不舒服,然后思考如何将你学到的东西应用到你需要的东西上。
建议的基本框架看起来不错,但定义的错误对象太有限。人们通常不能用一个值来表达问题,而是需要一系列问题和原因。
我做了一点研究,发现返回错误(异常)最常见的格式是以下形式的结构:
{
"success": false,
"error": {
"code": "400",
"message": "main error message here",
"target": "approx what the error came from",
"details": [
{
"code": "23-098a",
"message": "Disk drive has frozen up again. It needs to be replaced",
"target": "not sure what the target is"
}
],
"innererror": {
"trace": [ ... ],
"context": [ ... ]
}
}
}
这是OASIS数据标准OASIS OData提出的格式,似乎是最标准的选项,但目前任何标准的采用率似乎都不高。此格式与JSON-RPC规范一致。
您可以在以下位置找到实现此功能的完整开源库:Mendocino JSON Utilities。该库支持JSON对象以及异常。
详细信息在我关于JSON REST API中的错误处理的博客文章中讨论
我曾经遵循这个标准,在客户端层非常好、简单、干净。
通常,HTTP状态为200,所以这是我在顶部使用的标准检查。我通常使用以下JSON
我还使用API的模板
dynamic response;
try {
// query and what not.
response.payload = new {
data = new {
pagination = new Pagination(),
customer = new Customer(),
notifications = 5
}
}
// again something here if we get here success has to be true
// I follow an exit first strategy, instead of building a pyramid
// of doom.
response.success = true;
}
catch(Exception exception){
response.success = false;
response.message = exception.GetStackTrace();
_logger.Fatal(exception, this.GetFacadeName())
}
return response;
{
"success": boolean,
"message": "some message",
"payload": {
"data" : []
"message": ""
... // put whatever you want to here.
}
}
在客户端层上,我将使用以下内容:
if(response.code != 200) {
// woops something went wrong.
return;
}
if(!response.success){
console.debug ( response.message );
return;
}
// if we are here then success has to be true.
if(response.payload) {
....
}
请注意我是如何提前打破厄运金字塔的。
他们对大型软件巨头(谷歌、脸书、推特、亚马逊等)的rest api响应格式没有达成一致,尽管上面的答案中提供了许多链接,一些人已经尝试将响应格式标准化。
由于API的需求可能不同,很难让每个人都加入并同意某种格式。如果您有数百万用户使用您的API,为什么要更改响应格式?
以下是我对谷歌、推特、亚马逊和互联网上一些帖子的回应格式的看法:
https://github.com/adnan-kamili/rest-api-response-format
交换文件:
https://github.com/adnan-kamili/swagger-sample-template