示例
本页面包含有关如何应用规范各个部分的更多示例。
稀疏字段集
有关 稀疏字段集 如何工作的示例。
基本请求
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[articles]
和 fields[people]
参数的请求
GET /articles?include=author&fields[articles]=title,body,author&fields[people]=name HTTP/1.1
注意:以上示例 URI 显示未编码的
[
和]
字符,仅为可读性。在实践中,应按基础规范中的说明对这些字符进行百分比编码。请参阅“参数名称中的方括号”。
这里我们希望 articles
对象仅具有字段 title
、body
和 author
,而 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": {
"totalPages": 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 显示未编码的
[
和]
字符,仅为可读性。在实践中,应按基础规范中的说明对这些字符进行百分比编码。请参阅“参数名称中的方括号”。
注意:将诸如
"totalPages"
之类的属性放在"meta"
中可以是方便地向客户端指示集合中总页数的一种方式(与"last"
链接相反,后者只给出最后一页的 URI)。但是,所有"meta"
值都是特定于实现的,因此您可以随意调用此成员("total"
、"count"
等),也可以完全不使用它。
错误对象
有关 错误对象 如何工作的示例。
基本错误对象
在以下响应中,服务器表示在创建/更新资源时遇到了错误,并且该错误是由无效的 "firstName"
属性引起的
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
"errors": [
{
"status": "422",
"source": { "pointer": "/data/attributes/firstName" },
"title": "Invalid Attribute",
"detail": "First name must contain at least two characters."
}
]
}
错误对象中的每个成员都是可选的,但它们都有助于通过提供更多详细信息来帮助客户端。
source
成员用于 指示请求文档的哪一部分导致了错误。
title
和 detail
成员类似,但 detail
特定于此问题的发生,而 title
更通用。
status
成员表示与问题关联的 HTTP 状态代码。当一次返回多个错误时(见下文),它非常有用,因为 HTTP 响应本身只能有一个状态代码。但是,它对于单个错误也很有用,可以避免客户端查看 HTTP 标头,或者在将 JSON:API 用于未来可能正式支持的非 HTTP 协议时。
多个错误
当单个请求响应中出现多个错误时,服务器只需将每个错误添加到 errors
数组中
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json
{
"errors": [
{
"status": "403",
"source": { "pointer": "/data/attributes/secretPowers" },
"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."
}
]
}
错误对象上唯一的唯一性约束是 id
字段。因此,同一属性上的多个错误可以分别给出自己的错误对象。以下示例显示了 "firstName"
属性上的多个错误
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
"errors": [
{
"source": { "pointer": "/data/attributes/firstName" },
"title": "Invalid Attribute",
"detail": "First name must contain at least two characters."
},
{
"source": { "pointer": "/data/attributes/firstName" },
"title": "Invalid Attribute",
"detail": "First name must contain an emoji."
}
]
}
注意:在以上带有 422 状态代码的响应中,
400 Bad Request
也是可以接受的。(更多详细信息。)JSON:API 对 400 与 422 不持立场。
错误代码
错误对象的 code
成员包含表示所遇到的问题类型的特定于应用程序的代码。 code
与 title
类似,因为两者都标识了一种通用的问题类型(与 detail
不同,后者特定于问题的特定实例),但是通过编程方式处理 code
比较容易,因为由于本地化,“相同”的 title
可能以不同的形式出现。
对于以下示例,假设 API 文档指定了以下映射
代码 | 问题 |
---|---|
123 | 值太短 |
225 | 密码缺少字母、数字或标点符号 |
226 | 密码不匹配 |
227 | 密码不能是最近五个密码之一 |
"password"
属性上的多个错误,错误 code
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
"jsonapi": { "version": "1.1" },
"errors": [
{
"code": "123",
"source": { "pointer": "/data/attributes/firstName" },
"title": "Value is too short",
"detail": "First name must contain at least two 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
顶级成员,还包含 jsonapi
顶级成员。错误响应不能包含顶级 data
成员,但可以包含 JSON:API 定义的所有其他顶级成员。
另外,请注意,第三个错误对象缺少 detail
成员(可能是出于安全原因)。同样,所有错误对象成员都是可选的。
高级 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
指向文档的顶层 (""
)。(指向“/”将是对请求文档 {"": "some value"}
中的字符串 "some value"
的适当引用。指向 "/data"
将是无效的,因为请求文档在 "/data"
上没有值,并且 source
始终是相对于请求文档给出的。)
如果服务器无法将请求解析为有效的 JSON,包括 source
就没有意义(因为没有 JSON 文档供 source
引用)。以下是如何让服务器对无效的 JSON 文档做出响应
{
"errors": [{
"status": "400",
"detail": "JSON parse error - Expecting property name at line 1 column 2 (char 1)."
}]
}
无效的查询参数
source
成员还可以用于指示错误源于 URI 查询参数问题,如下所示
GET /api/posts/1?include=author 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 `author` relationship path."
}
]
}
在大多数情况下,JSON:API 要求服务器在遇到 JSON:API 定义的查询参数的无效值时返回错误。但是,对于特定于 API 的查询参数(即,JSON:API 未定义的查询参数),服务器可以选择忽略无效参数并让请求成功,而不是返回错误。特定于 API 的查询参数必须包含一个非 a-z 字符。
其他无效参数示例包括:?fields[people]=
(无效参数名称;应该是 fields[people]
)和 ?redirect_to=http%3A%2F%2Fwww.owasp.org
(无效参数,在本例中为网络钓鱼攻击)等。