标准的JSON API响应格式?

是否存在用于构buildAPI的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!" } } 

是的,已经出现了一些标准(虽然标准的定义有一些自由度):

  1. JSON API – JSON API也包括创build和更新资源,而不仅仅是响应。
  2. JSend – 简单和可能你已经在做什么。
  3. OData JSON协议 – 非常复杂。
  4. 哈尔 – 像OData,但旨在成为像HATEOAS 。

还有JSON API描述格式:

  • 昂首阔步
    • JSON模式 (使用大招,但你可以使用它独立)
  • WADL在JSON中
  • 肾错构瘤
  • HAL因为HATEOAS在理论上是自我描述的。

Google JSON指南

成功响应返回data

 { "data": { "id": 1001, "name": "Wing" } } 

错误响应返回error

 { "error": { "code": 404, "message": "ID not found" } } 

如果你的客户端是JS,你可以使用if ("error" in response) {}来检查是否有错误。

我想一个事实上的标准并没有真正出现(也许永远不会)。 但不pipe,这里是我的意思:

成功的要求:

 { "status": "success", "data": { /* Application-specific data would go here. */ }, "message": null /* Or optional success message */ } 

请求失败:

 { "status": "error", "data": null, /* or optional error payload */ "message": "Error xyz has occurred" } 

优点:成功和错误情况下的顶级要素相同

缺点:没有错误代码,但是如果你愿意,你可以改变状态成为(成功或失败)代码,或者你可以添加另一个名为“代码”的顶级项目。

假设你的问题是关于REST的web服务devise,更准确地说是关于成功/错误。

我认为有3种不同的devise。

  1. 使用HTTP状态码来表明是否有错误,并试图限制自己的标准(通常它应该足够了)。

    • 优点:这是一个独立于你的api的标准。
    • 缺点:关于真正发生的事情的信息较less。
  2. 使用HTTP状态+ json正文 (即使它是一个错误)。 为错误定义一个统一的结构(例如:代码,消息,原因,types等)并将其用于错误,如果成功则返回预期的json响应。

    • 优点:在使用现有的HTTP状态代码时仍然是标准的,并且返回一个描述错误的json(你提供了关于发生的事情的更多信息)。
    • 缺点:输出json会根据错误或成功而有所不同。
  3. 忘记http状态 (例如always状态200),总是使用json,并在响应的根目录添加一个布尔值responseValid和一个错误对象(代码,消息等),如果它是一个错误将被填充,否则其他字段(成功)被填充。

    • 优点:客户端只处理作为jsonstring的响应主体,并忽略状态(?)。

    • 缺点:不太标准。

这取决于你select:)

根据API,我会select2或3(我更喜欢json rest apis的2)。 我在deviseREST API中遇到的另一件事情是每个资源(url)的文档的重要性:参数,主体,响应,头文件等等。

我也build议你使用jersey(jax-rs实现)+ genson (java / json databinding库)。 你只需要在你的类path中放置genson + jersey,并自动支持json。

编辑:

  • 解决scheme2是最难实施的,但其优势在于,您可以很好地处理例外情况,而不仅仅是业务错误,最初的努力更重要,但是您长期获胜。

  • 解决scheme3在服务器端和客户端都很容易实现,但是它不是很好,因为你不得不把你想要返回的对象封装在一个包含responseValid +错误的响应对象中。

我不会自称这是一个标准,所以我会用“我更喜欢”的forms。

我更喜欢简洁的回应(当请求列表/文章我想要一个JSON数组文章)。

在我的devise中,我使用HTTP进行状态报告, 200只返回有效载荷。

400返回请求错误的消息:

 {"message" : "Missing parameter: 'param'"} 

如果模型/控制器/ URI不存在,则返回404

如果我的处理出现错误,我会返回501 ,并提示消息:

 {"message" : "Could not connect to data store."} 

从我所看到的不lessREST架构都倾向于这些方面。

理由

JSON应该是一个有效载荷格式,它不是一个会话协议。 冗长的session-ish有效载荷的全部概念来自XML / SOAP世界以及各种导致这些臃肿devise的错误select。 当我们意识到这一切都是头痛的时候,REST / JSON的全部就是KISS,并且坚持HTTP。 我不认为JSend中有任何远程标准 ,特别是其中没有更详细的标准。 XHR会对HTTP响应做出反应,如果你使用jQuery来处理你的AJAX(就像大多数人一样),你可以使用try / catchdone() / fail()callback来捕获错误。 我看不出JSON封装状态报告是如何比这更有用的。

以下是instagram使用的json格式

 { "meta": { "error_type": "OAuthException", "code": 400, "error_message": "..." } "data": { ... }, "pagination": { "next_url": "...", "next_max_id": "13872296" } } 

JSON的意义在于它是完全dynamic和灵活的。 把它转换成你想要的任何奇思妙想,因为它只是一组以单个节点为根的序列化的JavaScript对象和数组。

根节点的types取决于你,它所包含的内容取决于你,无论你是否将元数据与响应一起发送给你,无论你是将MIMEtypes设置为application/json还是将其保留为text/plain (只要你知道如何处理边缘情况)。

构build一个你喜欢的轻量级模式。
就我个人而言,我发现用于在线游戏的分析跟踪和mp3 / ogg服务和图像库服务以及文本消息和networking数据包以及博客post和博客评论具有非常不同的要求发送和接收的内容以及应该如何消费。

所以我最不希望做的就是尽量使每个标准符合相同的标准,即基于XML2.0或者其他标准。

也就是说,使用对有意义的模式有很多需要说明的,并且经过深思熟虑。
只要阅读一些API反应,注意你喜欢什么,批评你不喜欢的东西,把这些批评写下来,理解他们为什么擦你错误的方式,然后考虑如何将你学到的东西应用到你所需要的东西上。

为了什么是值得的,我做了不同的事情。 一个成功的调用只有JSON对象。 我不需要更高级的JSON对象,它包含一个成功的字段指示true和一个有JSON对象的有效载荷字段。 我只是返回相应的JSON对象,使用200或其他适当的200范围内的标题中的HTTP状态。

但是,如果出现错误(400系列中的某个错误),则返回格式正确的JSON错误对象。 例如,如果客户端使用电子邮件地址和电话号码发送用户,其中一个格式不正确(即我不能将其插入到我的基础数据库中),我将返回如下所示的内容:

 { "description" : "Validation Failed" "errors" : [ { "field" : "phoneNumber", "message" : "Invalid phone number." } ], } 

这里重要的一点是,“field”属性必须与JSON字段完全匹配,无法validation。 这可以让客户确切地知道他们的要求出了什么问题。 此外,“消息”位于请求的语言环境中。 如果“emailAddress”和“phoneNumber”都是无效的,则“errors”数组将包含两个条目。 一个409(冲突)JSON响应正文可能是这样的:

 { "description" : "Already Exists" "errors" : [ { "field" : "phoneNumber", "message" : "Phone number already exists for another user." } ], } 

通过HTTP状态代码和这个JSON,客户端可以用确定的方式来响应错误,而不会创build一个新的错误标准来尝试完成replaceHTTP状态代码。 请注意,这些只发生在400个错误的范围内。 对于200范围内的任何事情,我可以只返回任何适当的东西。 对我来说,它通常是一个HAL类的JSON对象,但在这里并不重要。

我想添加的一件事情是在“错误”数组条目或JSON对象本身的根目录中的数字错误代码。 但是到目前为止,我们并不需要它。

RFC 7807:HTTP API的问题细节目前是我们最接近官方标准的事情。

JSON-RPC 2.0定义了一个标准的请求和响应格式,在使用REST API之后是一片新鲜空气。

尽pipe在上面的答案中已经提供了很多链接,但有些人试图规范响应格式,但他们对于Google,Facebook,Twitter,Amazon等大型软件巨头的其他api响应格式没有达成一致。

由于API的需求可能会有所不同,因此很难让所有人都能接受并同意某种格式。 如果你有数百万用户使用你的API,你为什么要改变你的响应格式?

以下是我对谷歌,Twitter,亚马逊和互联网上的一些post启发的响应格式:

https://github.com/adnan-kamili/rest-api-response-format

Swagger文件:

https://github.com/adnan-kamili/swagger-sample-template