建議

本節包含 JSON:API 實作的建議。這些建議旨在在基本 JSON:API 規格範圍之外的領域建立一致性。

命名

規格對 JSON:API 文件中成員(即鍵)的命名方式 đặt ra 一些 硬性限制。為了進一步標準化成員名稱,尤其是在混合不同作者撰寫的設定檔時,也建議遵循以下規則

  • 成員名稱**應該**使用駝峰式大小寫(即 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 透過將 /relationships/ 和關係名稱附加到資源的 URL 來組成。

例如,相片的 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 已接受 以及 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 確定,因為伺服器正在成功報告狀態。或者,伺服器可以返回 Retry-After 標頭,以指導客戶端應等待多長時間才能再次檢查。建議使用 Retry-After: 0 來實現重試時間短於 1 秒的建議。

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 查看其他 以及 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.dev.org.tw/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.