示例

本页包含了额外的示例,用以说明如何应用规范的各个部分。

稀疏字段集

稀疏字段集如何工作的示例:

基本请求:

GET /articles?include=author HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!",
      "body": "The shortest article. Ever.",
      "created": "2015-05-22T14:56:29.000Z",
      "updated": "2015-05-22T14:56:28.000Z"
    },
    "relationships": {
      "author": {
        "data": {"id": "42", "type": "people"}
      }
    }
  }],
  "included": [
    {
      "type": "people",
      "id": "42",
      "attributes": {
        "name": "John",
        "age": 80,
        "gender": "male"
      }
    }
  ]
}

fields参数的请求:

GET /articles?include=author&fields[articles]=title,body,author&fields[people]=name HTTP/1.1

注:以上URI示例显示未编码的’[‘和’]’字符必须是基本规范中注明的%编码。

我们要想 articles 对象只拥有 titlebodyauthor 字段,而people对象只拥有name 字段。

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!",
      "body": "The shortest article. Ever."
    },
    "relationships": {
      "author": {
        "data": {"id": "42", "type": "people"}
      }
    }
  }],
  "included": [
    {
      "type": "people",
      "id": "42",
      "attributes": {
        "name": "John"
      }
    }
  ]
}

注意你要加关联名在include 和“fields”中(因为“关联”也是字段),否则,你会得到:

GET /articles?include=author&fields[articles]=title,body&fields[people]=name HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!",
      "body": "The shortest article. Ever."
    }
  }],
  "included": [
    {
      "type": "people",
      "id": "42",
      "attributes": {
        "name": "John"
      }
    }
  ]
}

注:以上URI示例表明未编码的‘[’和’]’字符仅仅是为了可读性。实际应用中,这些字符必须是基本规范中注明的%编码。

分页链接

有关如何添加基于页面的策略的分页链接示例:

基本请求:

GET /articles?page[number]=3&page[size]=1 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "meta": {
    "total-pages": 13
  },
  "data": [
    {
      "type": "articles",
      "id": "3",
      "attributes": {
        "title": "JSON API paints my bikeshed!",
        "body": "The shortest article. Ever.",
        "created": "2015-05-22T14:56:29.000Z",
        "updated": "2015-05-22T14:56:28.000Z"
      }
    }
  ],
  "links": {
    "self": "http://example.com/articles?page[number]=3&page[size]=1",
    "first": "http://example.com/articles?page[number]=1&page[size]=1",
    "prev": "http://example.com/articles?page[number]=2&page[size]=1",
    "next": "http://example.com/articles?page[number]=4&page[size]=1",
    "last": "http://example.com/articles?page[number]=13&page[size]=1"
  }
}

注:以上URI示例表明未编码的[]字符仅仅是为了可读性。实际应用中,这些字符必须是基本规范中注明的%编码。 注:在"meta"中加入如"total-pages"这样的属性能够方便的向客户端表明在一个集合中的页面总数(而不是"last"链接,它仅仅给出了最后一页的URI)。然而,所有的"meta"值都是特定于实现的,所以你怎么称呼这个成员随你便("total""count"等)或者根本不用它。

«««< HEAD

Error 对象

=======

Error 对象

72fd7c5e73f42c86e2102c1116147bb9d9c202a5

error 对象使用示例:

基本的Error对象

在以下的响应中,服务器表明它在创建/更新资源时发生了错误,而错误是由无效的"first name"引起的:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "status": "422",
      "source": { "pointer": "/data/attributes/first-name" },
      "title":  "Invalid Attribute",
      "detail": "First name must contain at least three characters."
    }
  ]
}

error对象中的每个成员是可选的,但都是为了辅助客户端,提供额外的细节信息。

source成员是用来表明请求文档的哪个部分发生了错误。

titledetail成员也是如此,不过detail成员是发生的问题的详细信息,而title是比较通用的信息。

status成员代表与问题相关的HTTP状态码。HTTP响应本身只能有一个状体码,一旦有多个错误返回时,它是很有用的(见下文)。然而,它也可用于单个错误,可保存客户端的查询HTTP头问题,或使用在非HTTP协议之上的JSON API,它或许会在不久后得到官方支持。

多个错误

当对单个请求的响应中出现多个错误时,服务器仅需将每个错误添加到errors数组中:

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "status": "403",
      "source": { "pointer": "/data/attributes/secret-powers" },
      "detail": "Editing secret powers is not authorized on Sundays."
    },
    {
      "status": "422",
      "source": { "pointer": "/data/attributes/volume" },
      "detail": "Volume does not, in fact, go to 11."
    },
    {
      "status": "500",
      "source": { "pointer": "/data/attributes/reputation" },
      "title": "The backend responded with an error",
      "detail": "Reputation service not responding after three requests."
    }
  ]
}

对于error对象,只有id字段需要唯一性约束。那样,同一属性的多个错误可以单独分配它们自己的error对象。以下示例显示了有关"first name"属性的多个错误:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "source": { "pointer": "/data/attributes/first-name" },
      "title": "Invalid Attribute",
      "detail": "First name must contain at least three characters."
    },
    {
      "source": { "pointer": "/data/attributes/first-name" },
      "title": "Invalid Attribute",
      "detail": "First name must contain an emoji."
    }
  ]
}

注:以上是包含422状态码的响应,400 Bad Request也是可以接受的。(更多细节)。)JSON API没有对400和422作比对。

错误码

Error对象的code成员包含一个特定于应用的代码,它代表所遇问题的类型。在识别一个问题的一般类型(不像detail,只用于特定实例问题的详细信息),ccode和ttitle相似。不过能用code以相对容易的编程方式处理,因为“相同”title由于本地化,会出现在不同的格式中。

代码 问题
123 值太短
225 密码缺少一个字母、数字或标点字符
226 密码不匹配
227 密码不能为最近使用过的五个密码中的一个

包含错误code的有关"password"属性的多个错误:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json

{
  "jsonapi": { "version": "1.0" },
  "errors": [
    {
      "code":   "123",
      "source": { "pointer": "/data/attributes/first-name" },
      "title":  "Value is too short",
      "detail": "First name must contain at least three characters."
    },
    {
      "code":   "225",
      "source": { "pointer": "/data/attributes/password" },
      "title": "Passwords must contain a letter, number, and punctuation character.",
      "detail": "The password provided is missing a punctuation character."
    },
    {
      "code":   "226",
      "source": { "pointer": "/data/attributes/password" },
      "title": "Password and password confirmation do not match."
    }
  ]
}

注意这个响应不仅包含errors顶层(top-level)成员,也包括jsonapi顶层成员。错误响应不能包含顶层data成员,但可以包含所有其他JSON API 定义的顶层成员。

同样,注意第三个error对象缺少detail成员(或许是为了安全起见)。再次,所有error对象成员都是可选的。

source高级应用

在以下示例中,用户是在发送一个无效JSON API请求,因为它丢失了data成员。

PATCH /posts/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{ "datum": [ ] }

因此,服务器回应:

HTTP/1.1 422 Unprocesssable Entity
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "source": { "pointer": "" },
      "detail":  "Missing `data` Member at document's top level."
    }
  ]
}

无效查询参数

source成员也可以用来表明错误源自一个URI查询参数问题,就像这样:

GET /api/posts/1?include=auther HTTP/1.1
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "source": { "parameter": "include" },
      "title":  "Invalid Query Parameter",
      "detail": "The resource does not have an `auther` relationship path."
    }
  ]
}

多数情况下,当服务器遇到一个对于定义了的JSON API查询参数无效值时,JSON API需要服务器返回一个错误。然而,对于特定API查询参数(如,那些JSON API 没有定义的),服务器要选择忽略一个无效的参数,并请求成功,而非回应一个错误。特定API的查询参数必须包含一个非’a’到’z’的字符。

其他无效参数示例包括:?felds[people]= (无效的参数名;应该是ffields[people]) 及 ?redirect_to=http%3A%2F%2Fwww.owasp.org (无效参数,在这个例子中,是一个网络钓鱼攻击),等等。

本页由Rehair翻译。