建议

本节包含 JSON:API 实现的建议。这些建议旨在为超出 JSON:API 规范范围的领域建立一致性。

命名

规范对 JSON:API 文档中成员(即键)的命名方式施加了一定的 硬性限制。为了进一步标准化成员名称,这在混合来自不同方撰写的配置文件时尤为重要,以下规则也建议使用

  • 成员名称 **应** 使用驼峰式命名法(即 wordWordWord
  • 成员名称 **应** 以 “a-z” (U+0061 到 U+007A) 字符开头和结尾
  • 成员名称 **应** 只包含 ASCII 字母数字字符(即 “a-z”、”A-Z” 和 “0-9”)

URL 设计

参考文档

在确定 API 的 URL 结构时,需要考虑所有资源都存在于单个 “参考文档” 中,其中每个资源都可以在唯一的路径下访问。资源在该文档的顶层按类型进行分组。单个资源在这些类型化的集合中按 ID 索引。单个资源内的属性和链接根据上述资源对象结构进行唯一寻址。

参考文档的概念用于确定资源以及其关系的适当 URL。重要的是要理解,此参考文档的结构与用于传输资源的文档略有不同,因为它们的目标和约束不同。例如,参考文档中的集合表示为集合,因为成员必须通过 ID 寻址,而传输文档中的集合表示为数组,因为顺序很重要。

资源集合的 URL

建议资源集合的 URL 由资源类型组成。

例如,类型为 photos 的资源集合将具有 URL

/photos

单个资源的 URL

将资源集合视为按资源 ID 索引的集合。单个资源的 URL 可以通过将资源的 ID 附加到集合 URL 来形成。

例如,ID 为 "1" 的照片将具有 URL

/photos/1

正如基本规范中所述,每个关系可以公开两个 URL

  • “关系 URL” - 关系本身的 URL,在关系的 links 对象中使用 self 键标识。此 URL 允许客户端直接操作关系。例如,它将允许客户端从 post 中移除 author,而无需删除 people 资源本身。

  • “相关资源 URL” - 相关资源的 URL,在关系的 links 对象中使用 related 键标识。当获取时,它将相关资源对象作为响应的主要数据返回。

建议将关系 URL 构成,方法是在资源的 URL 后附加 /relationships/ 和关系的名称。

例如,照片的 comments 关系将具有 URL

/photos/1/relationships/comments

而照片的 photographer 关系将具有 URL

/photos/1/relationships/photographer

建议将相关资源 URL 构成,方法是在资源的 URL 后附加关系的名称。

例如,照片的 comments 的 URL 将为

/photos/1/comments

而照片的 photographer 的 URL 将为

/photos/1/photographer

由于这些 URL 表示关系中的资源,因此不应将其用作资源本身的 self 链接。相反,在形成 self 链接时,应继续使用单个资源 URL 的建议。

过滤

基本规范对服务器支持的过滤策略保持中立。 filter 查询参数系列保留用作任何过滤策略的基础。

建议希望根据关联关系对资源集合进行过滤的服务器通过允许组合 filter 与关联关系名称的查询参数来实现此目的。

例如,以下是请求与特定帖子相关联的所有评论的请求

GET /comments?filter[post]=1 HTTP/1.1

多个过滤值可以组合在逗号分隔的列表中。例如

GET /comments?filter[post]=1,2 HTTP/1.1

此外,可以将多个过滤器应用于单个请求

GET /comments?filter[post]=1,2&filter[author]=12 HTTP/1.1

基本规范对在资源响应中包含链接保持中立。但是,建议在响应文档中包含以下链接

  • 顶级链接,如自链接(对于整个响应)以及相对分页链接(如果适用)。
  • 资源级链接,如每个资源的自链接(如果资源是集合的一部分,则与顶级链接不同)。
  • 关系链接,用于资源的所有可用关系。

例如,对评论集合的请求可能提示以下响应

GET /comments HTTP/1.1

{
  "data": [{
      "type": "comments",
      "id": "1",
      "attributes": {
          "text": "HATEOS are the thing!"
      },
      "links": {
          "self": "/comments/1"
      },
      "relationships": {
        "author": {
          "links": {
            "self": "/comments/1/relationships/author",
            "related": "/comments/1/author"
          }
        },
        "articles": {
          "links": {
            "self": "/comments/1/relationships/articles",
            "related": "/comments/1/articles"
          }
        }
      }
  }],
  "links": {
      "self": "/comments"
  }
}

支持缺乏 PATCH 的客户端

某些客户端(如 IE8)缺乏对 HTTP 的 PATCH 方法的支持。希望支持这些客户端的 API 服务器建议在客户端包含 X-HTTP-Method-Override: PATCH 标头的情况下,将 POST 请求视为 PATCH 请求。这允许缺乏 PATCH 支持的客户端通过简单地添加标头来完成更新请求。

格式化日期和时间字段

尽管 JSON:API 未指定日期和时间字段的格式,但建议服务器与 ISO 8601 保持一致。 此 W3C 注解 提供了推荐格式的概述。

异步处理

考虑需要创建资源且操作需要很长时间才能完成的情况。

POST /photos HTTP/1.1

请求 **应** 返回状态 202 Accepted,并在 Content-Location 标头中包含一个链接。

HTTP/1.1 202 Accepted
Content-Type: application/vnd.api+json
Content-Location: https://example.com/photos/jobs/5234

{
  "data": {
    "type": "jobs",
    "id": "5234",
    "attributes": {
      "status": "Pending request, waiting other process"
    },
    "links": {
      "self": "/photos/jobs/5234"
    }
  }
}

要检查作业处理的状态,客户端可以向之前提供的地址发送请求。

GET /photos/jobs/5234 HTTP/1.1
Accept: application/vnd.api+json

对仍处于挂起状态的作业的请求 **应** 返回状态 200 OK,因为服务器已成功报告状态。可选地,服务器可以返回 Retry-After 标头,以指导客户端应等待多长时间才能再次检查。建议重试时间早于 1 秒,可以使用 Retry-After: 0 实现。

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

{
  "data": {
    "type": "jobs",
    "id": "5234",
    "attributes": {
      "status": "Pending request, waiting other process"
    },
    "links": {
      "self": "/photos/jobs/5234"
    }
  }
}

作业处理完成后,请求 **应** 返回状态 303 See other,并在 Location 标头中包含一个链接。

HTTP/1.1 303 See other
Content-Type: application/vnd.api+json
Location: https://example.com/photos/4577

撰写配置文件

配置文件是一种机制,可以由文档的发送者使用,以对文档的内容做出承诺,而不会添加或更改 JSON:API 规范的基本语义。例如,配置文件可能表明所有资源对象都将具有 timestamps 属性字段,并且 timestamps 对象的成员将使用 ISO 8601 日期时间格式进行格式化。

配置文件是对这些承诺的独立规范。以下示例说明了如何撰写上述配置文件

# Timestamps profile

## Introduction

This page specifies a profile for the `application/vnd.api+json` media type,
as described in the [JSON:API specification](https://jsonapi.fullstack.org.cn/format/).

This profile allows every resource in a JSON:API document to represent
significant timestamps in a consistent way.

## Document Structure

Every resource object **MUST** include a `timestamps` member in its associated
`attributes` object. If this member is present, its value **MUST** be an object that
**MAY** contain at least one of the following members:

* `created`
* `updated`

The value of each member **MUST** comply with the variant of ISO 8601 used by
JavaScript's `JSON.stringify` method to format Javascript `Date` objects.