範例

此頁面包含關於如何應用規格各個部分的額外範例。

精簡欄位集

精簡欄位集 如何運作的範例。

基本請求

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 物件僅包含 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"
      }
    }
  ]
}

請注意,您必須在 includefields 中都加入關聯名稱(因為關聯也是欄位),否則您會得到

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" 中可以方便地向客戶端指示集合中的總頁數(與僅提供最後一頁 URI 的 "last" 連結相反)。但是,所有 "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 成員用於指示請求文件中哪個部分導致了錯誤。

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/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 成員包含一個應用程式特定的程式碼,表示遇到的問題類型。codetitle 相似,因為兩者都識別了一般類型的問題(與特定於問題特定實例的 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(無效的參數,在本例中為網路釣魚攻擊)等。