标准的JSON API响应格式?

FtD*_*Xw6 642 json response request

是否存在用于从API构造JSON响应的标准或最佳实践?显然,每个应用程序的数据都是不同的,所以我不关心,而是"响应样板",如果你愿意的话.我的意思的一个例子:

成功要求:

{
  "success": true,
  "payload": {
    /* Application-specific data would go here. */
  }
}
Run Code Online (Sandbox Code Playgroud)

请求失败:

{
  "success": false,
  "payload": {
    /* Application-specific data would go here. */
  },
  "error": {
    "code": 123,
    "message": "An error occurred!"
  }
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*ent 588

是的,已经出现了一些标准(尽管对标准的定义有一些自由):

  1. JSON API - JSON API还包括创建和更新资源,而不仅仅是响应.
  2. JSend - 简单而且可能你正在做的事情.
  3. OData JSON协议 - 非常复杂.
  4. HAL - 像OData一样,但想成为像HATEOAS一样的.

还有JSON API描述格式:

  • 谢谢.特别是JSend正是我想要的.它与我正在做的类似,但有一些好处,我的方法没有.为了公平对待@trungly,JSend也非常接近他自己的答案. (14认同)
  • 特别是对于错误响应,我也喜欢[HTTP API的问题详细信息](http://datatracker.ietf.org/doc/draft-nottingham-http-problem/)RFC草案. (7认同)
  • [Google JSON Style Guide](https://google.github.io/styleguide/jsoncstyleguide.xml) 也是很好的参考 (3认同)

Ste*_*ing 177

Google JSON指南

成功回复 data

{
  "data": {
    "id": 1001,
    "name": "Wing"
  }
}
Run Code Online (Sandbox Code Playgroud)

错误响应返回 error

{
  "error": {
    "code": 404,
    "message": "ID not found"
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 首先,Google JSON指南建议使用双引号而不是单引号. (12认同)
  • 那些需要提供失败列表(如验证问题)的错误呢? (3认同)
  • 我不确定您是否可以从像 PlayJson 这样的服务器端 JSON API 处理这个问题,无论哪种方式都无关紧要。@Steel 你的链接坏了 (2认同)
  • @Xeoncross 点击“error”一词上的链接,Google 的页面给出了一个示例 (2认同)

tru*_*gly 115

我猜一个事实标准还没有真正出现(也许永远不会).但无论如何,这是我的看法:

成功要求:

{
  "status": "success",
  "data": {
    /* Application-specific data would go here. */
  },
  "message": null /* Or optional success message */
}
Run Code Online (Sandbox Code Playgroud)

请求失败:

{
  "status": "error",
  "data": null, /* or optional error payload */
  "message": "Error xyz has occurred"
}
Run Code Online (Sandbox Code Playgroud)

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

缺点:没有错误代码,但如果您愿意,您可以将状态更改为(成功或失败)代码,或者 - 您可以添加另一个名为"代码"的顶级项目.

  • 为了成功:如果标题中有“200”,为什么还需要“status”字段?只需直接返回数据对象即可。您知道这可能会给 TypeScript 等类型化 FE 语言带来额外的痛苦。 (4认同)
  • 是的,如果你使用POJO进行json解析,这是正确的方法!当我们使用POJO时,我们需要静态,非动态的json格式! (3认同)
  • 答案几乎是一份记录良好的[JSend](http://labs.omniti.com/labs/jsend)的副本,它简单而且非常有用.它们为典型的验证问题提供了第三个状态`fail`,而`error`仅用于db错误之类的致命错误. (3认同)

eug*_*gen 80

假设您的问题是关于REST Web服务设计,更准确地说是成功/错误.

我认为有3种不同类型的设计.

  1. 使用HTTP状态代码来指示是否存在错误,并尝试将自己限制为标准错误(通常应该足够).

    • 优点:这是一个独立于你的API的标准.
    • 缺点:关于真实情况的信息较少.
  2. 使用HTTP Status + json body(即使它是一个错误).为错误定义统一的结构(例如:代码,消息,原因,类型等)并将其用于错误,如果成功则返回预期的json响应.

    • 优点:仍然是标准的,因为您使用现有的HTTP状态代码并返回描述错误的json(您提供有关所发生情况的更多信息).
    • 缺点:输出json将根据错误或成功而变化.
  3. 忘记http状态(例如:总是状态200),总是使用json并在响应的根处添加一个布尔responseValid和一个错误对象(代码,消息等),否则将填充错误,否则其他字段(成功)填充.

    • 优点:客户端仅处理作为json字符串的响应主体并忽略状态(?).

    • 缺点:标准较低.

这取决于你选择:)

根据API我会选择2或3(我更喜欢2为json rest apis).我在设计REST Api时遇到的另一件事是每个资源(url)的文档的重要性:参数,正文,响应,标题等+示例.

我还建议你使用jersey(jax-rs实现)+ genson(java/json数据绑定库).您只需在类路径中删除genson + jersey并自动支持json.

编辑:

  • 解决方案2是最难实现的,但优点是您可以很好地处理异常,而不仅仅是业务错误,初始工作更重要,但您可以长期获胜.

  • 解决方案3很容易在服务器端和客户端上实现,但它不是很好,因为你必须在一个包含responseValid +错误的响应对象中封装你想要返回的对象.

  • 对于记录:HTTP状态代码不是标头. (7认同)
  • "响应不会是json,而是html." 错误!html与错误处理无关.响应可以是您支持的任何内容类型. (3认同)
  • 您说我应该“为错误定义统一的结构”和其他类似的建议,但这正是我要问的问题。我猜答案是“不,关于这种结构,没有标准或最佳实践”。 (2认同)
  • @アレックス HTTP 状态代码是 HTTP 响应标头状态行中的 3 位代码。该行之后是标题字段,通俗地也称为标题。 (2认同)

Boj*_*vic 19

我不会声称这是一个标准,因此我将使用"我更喜欢"的形式.

我更喜欢简洁的响应(当我要求一个JSON数组文章的/文章列表时).

在我的设计中,我使用HTTP进行状态报告,200只返回有效负载.

400返回请求错误的消息:

{"message" : "Missing parameter: 'param'"}
Run Code Online (Sandbox Code Playgroud)

如果model/controler/URI不存在,则返回404

如果我的处理有错误,我会返回501并带有一条消息:

{"message" : "Could not connect to data store."}
Run Code Online (Sandbox Code Playgroud)

从我所看到的,相当多的REST-ish框架倾向于沿着这些方向发展.

理由:

JSON应该是有效载荷格式,它不是会话协议.详细的session-ish有效载荷的整个想法来自XML/SOAP世界以及创建那些臃肿设计的各种错误选择.在我们意识到所有这一切都是一个巨大的问题之后,REST/JSON的重点就是KISS,并坚持使用HTTP.我不认为JSend 中有任何远程标准,特别是其中没有更冗长的标准.XHR会对HTTP响应作出反应,如果你为你的AJAX使用jQuery(就像大多数人一样)你可以使用try/ catchdone()/ fail()回调来捕获错误.我无法看到JSON中的封装状态报告是如何比这更有用的.

  • “ JSON是有效载荷格式...”。不,JSON是数据序列化格式。您可以使用它来传输所需的任何内容,包括会话协议或简单的有效负载。但是,您的KISS注释已达到目标,并且独立于JSON。最好使JSON专注于它的内容(如您所描述的成功数据或失败原因数据),而不是用一些必须不断组成并随后被剥离的杂乱的混合污染它。然后,您可以一路将其JSON数据存储在Couchbase中,然后将其按原样返回给应用程序。 (2认同)

Ber*_*pac 19

RFC 7807:用于HTTP API的问题详细信息是在目前我们有一个正式的标准最接近.


Muh*_*min 18

以下是Instagram正在使用的json格式

{
    "meta": {
         "error_type": "OAuthException",
         "code": 400,
         "error_message": "..."
    }
    "data": {
         ...
    },
    "pagination": {
         "next_url": "...",
         "next_max_id": "13872296"
    }
}
Run Code Online (Sandbox Code Playgroud)


rob*_*lco 16

对于它的价值,我以不同的方式做到这一点.成功调用只有JSON对象.我不需要更高级别的JSON对象,其中包含指示true的成功字段和具有JSON对象的有效负载字段.我只返回适当的JSON对象,其中包含200或者在200范围内适用于标题中HTTP状态的任何内容.

但是,如果出现错误(400系列中的某些内容),我将返回格式正确的JSON错误对象.例如,如果客户端在张贴的电子邮件地址和电话号码,其中一个用户的格式不正确(即我不能将它插入到我的底层数据库),我将返回是这样的:

{
  "description" : "Validation Failed"
  "errors" : [ {
    "field" : "phoneNumber",
    "message" : "Invalid phone number."
  } ],
}
Run Code Online (Sandbox Code Playgroud)

这里的重要部分是"field"属性必须与无法验证的JSON字段完全匹配.这允许客户确切地知道他们的请求出了什么问题.此外,"message"位于请求的区域设置中.如果"emailAddress"和"phoneNumber"都无效,那么"errors"数组将包含两者的条目.409(冲突)JSON响应正文可能如下所示:

{
  "description" : "Already Exists"
  "errors" : [ {
    "field" : "phoneNumber",
    "message" : "Phone number already exists for another user."
  } ],
}
Run Code Online (Sandbox Code Playgroud)

使用HTTP状态代码和此JSON,客户端具有以确定性方式响应错误所需的全部内容,并且它不会创建尝试完成替换HTTP状态代码的新错误标准.请注意,这些仅发生在400个错误的范围内.对于200范围内的任何东西,我都可以返回任何合适的东西.对我来说,它通常是类似HAL的JSON对象,但这并不重要.

我想添加的一件事是"错误"数组条目中的数字错误代码或JSON对象本身的根.但到目前为止,我们还没有需要它.


adn*_*ili 9

他们没有就大型软件巨头谷歌,Facebook,Twitter,亚马逊等公司的其他api响应格式达成一致,尽管上面的答案中提供了许多链接,有些人试图将响应格式标准化.

由于API的需求可能不同,因此很难让每个人都参与并同意某种格式.如果您有数百万用户使用您的API,为什么要更改您的响应格式?

以下是我对谷歌,Twitter,亚马逊以及互联网上的一些帖子启发的响应格式的看法:

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

Swagger文件:

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


Nor*_*ard 7

JSON的观点是它完全动态且灵活.将它弯曲到您想要的任何想法,因为它只是一组序列化的JavaScript对象和数组,以单个节点为根.

root节点的类型取决于你,它包含的内容取决于你,无论你是否发送元数据以及响应取决于你,是否将mime-type设置为application/jsontext/plain由你自己决定(只要你知道如何处理边缘情况).

构建您喜欢的轻量级架构.
就个人而言,我发现,分析,跟踪和MP3/OGG服务和图像画廊服务和短信和网络数据包的网络游戏和博客,帖文,博客,评论有着非常不同的要求在什么条件发送和收到的内容以及如何使用它们.

因此,在完成所有这些工作时,最后我想要的是尝试使每个符合相同的样板标准,该标准基于XML2.0或某些.

也就是说,使用对有意义且经过深思熟虑的模式有很多话要说.
只需阅读一些API回复,记下你喜欢什么,批评你不喜欢的东西,写下那些批评,理解为什么他们用错误的方式揉搓你,然后考虑如何将你学到的东西应用到你需要的东西上.

  • 感谢您的回复,但同样,我并不担心有效负载本身。虽然您的示例在_有效负载_内发送/接收的内容以及如何使用这些_有效负载_方面都有非常不同的要求,但它们都必须解决与_响应本身_相关的相同问题。也就是说,他们都需要确定请求是否成功。如果是,则继续处理。如果不是,那是哪里出了问题。这是我在问题中提到的所有 API 响应所共有的样板。 (2认同)
  • 我意识到这是一个空白的事情,我喜欢.我的问题的目的是询问结构是否有任何新兴标准.我没有问"什么是JSON以及我如何使用它",而是"我知道如何使用JSON返回/构造我想要的任何东西,但我想知道是否使用了任何标准结构或变得流行." 如果我被问题误解,我很抱歉.无论如何,谢谢你的回复. (2认同)

dna*_*ult 6

JSON-RPC 2.0定义了标准的请求和响应格式,并且在使用REST API之后令人耳目一新。