建議
本節包含 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
-
「關係 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.