API系列之JSON-API最新标准

简介

JSON API 是一个客户端应该如何如何请求或者修改资源,以及服务器端如何对这些请求作出回应。

JSON API 是为了最小化客户端以及服务器端的请求数量以及大量的数据交换。在不牺牲可读性和灵活性的前提下来提升效率。

JSON API 需要使用 application/vnd.api+json 协议来传输数据。

约定

文中的这些关键字 “MUST”,”MUST NOT”, “REQUIRED”, “SHALL”, “SHOULD”,”SHOULD NOT”, “RECOMMENDED”,”NAY” 以及
“OPTINAL” 都可以在 RFC 2119 标准中可以找到解释。

内容限定

客户端职责

客户端必须(MUST)在 JSON API 请求的时候都要在请求的头部加上 Content-Type:application/vnd.api+json,不带其他的任何参数。

客户端在 JSON API 请求的头部的 Accept 中必须(MUST)至少指明一次协议的类型而不带任何的参数。

客户端必须(MUST)忽略收到的响应为 application/vnd.api+json 类型中 Content-Type所携带的任何参数。

服务器端职责

服务器必须(MUST)发送不携带任何参数的 application/vnd.api+json 类型的响应。

服务器必须(MUST)响应 415 Unsupported Media Type 状态码,如果请求 Content-Type:application/vnd.api+json 中携带任何参数的话。

服务器必须(MUST)响应 406 Not Acceptable 状态码,如果一个请求的头部的 Accept 的加上了参数的话。

注意:这个内容协定要求在当前和未来的使用这个协议以及相关扩展的版本中都会存在。

文档结构

这个小节讨论 JSON API 文档的结构。这个协议已经被定义为 application/vnd.api+json。JSON API 文档已经被定义在 JavaScript Object Notation(JSON)[RFC7159]。

尽管请求和响应使用的是相同的协议类型,某些方面只适合其中的一个,这其中的区别在稍后会谈到。

除非特殊情况,否则通过这个规格定义的对象不能(MUST NOT)包含其他的任何成员。客户端和服务器的实现必须(MUST)忽略不在这个规范范围内的其他成员。

注意:这些条件允许规格通过添加改变的方法来进化。

顶层

一个 JSON 对象必须(MUST)是任何的 JSON API 请求和响应所携带数据的根结构,这个对象定义文档的顶层。

一个文档必须(MUST)至少包含一个以下的顶层成员:

  • data: 文档的主要数据
  • errors: 一个错误对象的数组
  • meta: 一个包含非标准信息的 meta 对象

    dataerrors 不能同时出现在同一个请求或者响应中。

一个文档可能(MAY)会包含以下任何的顶层成员:

  • jsonapi: 一个描述服务端实现的对象
  • links: 与主要数据相关的链接对象
  • included: 一个与主要数据有关联或者其他的资源对象的数组。

如果文档的顶层没有 data 键,这个 included 成员也不能(MUST NOT) 出现在这里。

这个顶层链接对象可能(MAY)包含以下的成员:

  • self: 当前响应生成的链接
  • related: 一个相关的资源链接,当这个主要的数据代表一个资源的关系
  • pagination: 主数据的分页链接

文档中的主数据是指请求的资源的集合。

主数据必须(MUST)是以下两者中的一个:

  • 一个单独的资源对象,一个单独的资源标识对象或者是 null, 为了去请求目标资源
  • 资源对象数组,资源标识对象的数组或者一个 null 的数组,为了请求目标资源集合

举个例子,下面的数据就是一个单独的资源对象:

1
2
3
4
5
6
7
8
9
10
11
12
{
"data": {
"type": "articles",
"id": "1",
"attributes": {
// ... this article's attributes
},
"relationships": {
// ... this article's relationships
}
}
}

下面就是一个资源的标识对象,指代一些资源:

1
2
3
4
5
6
{
"data": {
"type": "articles",
"id": "1"
}
}

一个资源的集合必须用一个数组来表现,即使只有一项内容或者为空。

资源对象

资源对象 在 JSON API 的文档中代表资源。

一个资源必须(MUST)包含至少以下两个顶层成员:

  • id
  • type

例外: 当这个资源代表一个即将要被传送到服务器端创建的时候,这个 `id 可以被省略。

另外,一个资源对象可能(MAY)包含以下的顶层成员:

  • attributes: 代表资源数据的属性对象
  • relationships: 描述这个对象与 JSON API 其他对象关系的关系对象
  • links: 包含其他资源的链接对象
  • meta: 包含对象非属性数据的 meta 对象

一个 article 对象可能是如下的表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"type": "articles",
"id": "1",
"attributes": {
"title": "Rails is Omakase"
},
"relationships": {
"author": {
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
},
"data": { "type": "people", "id": "9" }
}
}
}
唯一标识