Apidog

オールインワン協働API開発プラットフォーム

API設計

APIドキュメント

APIデバッグ

APIモック

API自動テスト

JSON:API仕様の完全入門

Nikki Alessandro

Nikki Alessandro

Updated on 5月 19, 2025

REST(Representational State Transfer)は、Webサービス構築のための基礎的なアーキテクチャスタイルを提供します。しかし、リクエストとレスポンスのフォーマットに関する多くの側面は未定義のままです。この曖昧さにより、一貫性の欠如、開発オーバーヘッドの増加、API利用者の学習曲線の急勾配化を招く可能性があります。ここで登場するのがJSON:APIです。これは、JSONでAPIを構築するための標準化された規約ベースのアプローチを提供する仕様です。

この包括的なガイドでは、JSON:API仕様を深く掘り下げ、そのコアコンセプト、構造、強力な機能を探求します。リソースの取得、作成、更新、削除、リレーションシップの管理、エラー処理、データ転送の最適化に関するそのメカニズムを分析し、堅牢で効率的なAPIを設計・利用するための知識を提供します。

💡
美しいAPIドキュメントを生成する優れたAPIテストツールをお探しですか?

開発チームが最大限の生産性で連携するための、統合されたオールインワンプラットフォームをお探しですか?

Apidogはあなたのすべての要求に応え、Postmanをより手頃な価格で置き換えます
ボタン

なぜJSON:APIなのか?解説:

技術的な複雑さに入る前に、JSON:APIが解決しようとしている問題を理解することが重要です。共通の規約がない場合、API開発者はしばしばかなりの時間をかけて議論します。

  • ペイロード構造: リソースとその属性はどのように表現されるべきか?
  • リレーションシップの表現: 異なるリソース間のリンクはどのように伝えられるべきか?
  • データ取得戦略: クライアントは特定のフィールドを要求し、関連リソースを含め、ソート、ページネーション、フィルタリングを行うにはどうすればよいか?
  • エラー報告: エラーメッセージはどのようなフォーマットに従うべきか?

JSON:APIは、リクエストとレスポンスに対して明確で一貫したフォーマットを定義することで、これらに対応します。この標準化にはいくつかの重要な利点があります。

  • バイクシェッディングの削減: 一般的な設計上の疑問に答えを提供することで、JSON:APIはチームがAPI設計の細部に時間を費やすのではなく、アプリケーションのコアビジネスロジックに集中できるようにします。
  • 生産性の向上: 標準化されたフォーマットは、API提供者と利用者の両方にとってカスタムコードを減らすことを意味します。クライアントライブラリは、JSON:API準拠のサービスとやり取りするための多くのボイラープレートコードを処理するように開発できます。
  • 発見可能性と使いやすさの向上: 一貫したリンクリソースと、リソースおよびリレーションシップの明確な区別により、APIの理解とナビゲーションが容易になります。
  • データ転送の最適化: スパースフィールドセットや複合ドキュメントのような機能により、クライアントは必要なデータのみを要求でき、ペイロードサイズを最小限に抑え、HTTPリクエストの数を減らすことができます。
  • キャッシュの容易化: この仕様は、標準的なHTTPキャッシュメカニズムの使用を推奨しています。
  • 言語非依存: JSONベースであるため、本質的に言語非依存であり、多様な技術スタック全体での幅広い採用を促進します。

コアコンセプト:JSON:APIドキュメントの構成要素

JSON:APIの中心にあるのは、リソースという概念です。リソースは、「記事」、「ユーザー」、「製品」などの特定のタイプの個別のレコードです。リクエストまたはレスポンスのいずれであっても、すべてのJSON:APIドキュメントは特定の構造に従います。

ドキュメント構造:トップレベルメンバー

JSON:APIドキュメントは、以下のトップレベルメンバーの少なくとも1つを含まなければならないJSONオブジェクトです。

  • data:ドキュメントの「プライマリデータ」です。これは以下の場合があります。
  • 単一のリソースオブジェクト(例:特定の記事を取得する場合)。
  • リソースオブジェクトの配列(例:記事のコレクションを取得する場合)。
  • 単一のリソース識別子オブジェクト(to-oneリレーションシップを表す場合)。
  • リソース識別子オブジェクトの配列(to-manyリレーションシップを表す場合)。
  • null(例:to-oneリレーションシップが空の場合、または存在しない単一リソースのリクエストの場合)。
  • 空の配列[](例:to-manyリレーションシップが空の場合、またはコレクションのリクエストで結果が得られない場合)。
  • errors:処理エラーに関する詳細を提供するエラーオブジェクトの配列です。errorsが存在する場合、dataメンバーは存在してはなりません。
  • meta:仕様の他の部分に収まらない非標準のメタ情報を含むメタオブジェクトです。

さらに、ドキュメントは以下のトップレベルメンバーを含むこともあります。

  • jsonapi:サーバーの実装を説明するオブジェクトです。これには、version(サポートされている最高のJSON:APIバージョン)、ext(適用された拡張機能のURIの配列)、およびprofile(適用されたプロファイルのURIの配列)を含めることができます。
  • links:プライマリデータに関連するリンクオブジェクトです。これには、セルフリンク、関連リソースリンク、ページネーションリンクを含めることができます。
  • included:プライマリデータおよび/または互いに関連するリソースオブジェクトの配列です。「複合ドキュメント」に使用され、関連リソースをサイドローディングすることでHTTPリクエストの数を減らします。

リソースオブジェクト:データを表現する

リソースオブジェクトはJSON:APIの要であり、以下を含まなければなりません。

  • type:リソースのタイプを識別する文字列です(例:"articles""users")。これはリソースの名前空間を分け、異なるタイプ間のID衝突を回避するのに役立ちます。
  • id:そのタイプ内でリソースを一意に識別する文字列です。

リソースオブジェクトは以下を含むこともあります。

  • attributes:リソースに固有のデータを含む属性オブジェクトです。attributesオブジェクト内のキーは、リソースのプロパティを表します(例:記事の"title""body")。リレーションシップはattributesオブジェクトで表現してはなりません。
  • relationships:リソースと他のリソース間の接続を説明するリレーションシップオブジェクトです。
  • links:リソースに関連するリンクを含むリンクオブジェクトです。リソースの正規URLを指すselfリンクなどです。
  • meta:リソースに関する非標準のメタ情報を含むメタオブジェクトです。

リソースオブジェクトの例:JSON

{
  "type": "articles",
  "id": "1",
  "attributes": {
    "title": "JSON:API Unveiled",
    "body": "A deep dive into the specification...",
    "created_at": "2025-05-15T10:00:00Z",
    "updated_at": "2025-05-16T14:30:00Z"
  },
  "relationships": {
    "author": {
      "links": {
        "self": "/articles/1/relationships/author",
        "related": "/articles/1/author"
      },
      "data": { "type": "users", "id": "42" }
    },
    "comments": {
      "links": {
        "self": "/articles/1/relationships/comments",
        "related": "/articles/1/comments"
      },
      "data": [
        { "type": "comments", "id": "5" },
        { "type": "comments", "id": "12" }
      ]
    }
  },
  "links": {
    "self": "/articles/1"
  }
}

リソース識別子オブジェクト

リソース識別子オブジェクトは、typeidのみを含む、リソースの最小限の表現です。リレーションシップオブジェクト内で使用され、完全なリソースオブジェクトを埋め込むことなく他のリソースにリンクします。

リソース識別子オブジェクトの例:JSON

{ "type": "users", "id": "42" }

リンクオブジェクト

リンクオブジェクトは、APIをナビゲートするためのURLを提供します。一般的なリンクメンバーは以下を含みます。

  • self:リソースまたはドキュメント自体を表すリンクです。
  • related:関連リソースまたはコレクションへのリンクです。多くの場合、リレーションシップで使用され、実際の関連データを取得します。
  • ページネーションリンク:ページ付けされたコレクションをナビゲートするためのfirstlastprevnextです。

リンクは以下のように表現できます。

  • URLを含む単純な文字列。
  • リンクオブジェクト。これはhref(文字列URL)を含まなければならず、オプションでrel(リレーションタイプ)、describedby(説明ドキュメントへのリンク)、titletype(ターゲットのメディアタイプ)、hreflang、およびmetaオブジェクトを含めることができます。

リンクオブジェクトの例(リレーションシップ内):JSON

"links": {
  "self": "http://example.com/articles/1/relationships/author",
  "related": "http://example.com/articles/1/author"
}

メタオブジェクト

メタオブジェクトを使用すると、非標準のメタ情報を含めることができます。これは任意のキーと値のペアにすることができます。たとえば、metaオブジェクトには、著作権情報やデータに関連するタイムスタンプを含めることができます。

メタオブジェクトの例:JSON

"meta": {
  "copyright": "Copyright 2025 Example Corp.",
  "authors": ["John Doe"]
}

コンテンツネゴシエーション:適切な言語を話す

JSON:APIは独自のメディアタイプを定義しています:application/vnd.api+json

  • Acceptヘッダー: クライアントは、JSON:API準拠のレスポンスを期待していることを示すために、application/vnd.api+jsonメディアタイプを指定してこのヘッダーを送信しなければなりません。サーバーがAcceptヘッダー内のどのメディアタイプも満たせない場合、406 Not Acceptableステータスで応答しなければなりません。
  • Content-Typeヘッダー: クライアントとサーバーは、ボディにJSON:APIドキュメントを含むすべてのリクエストおよびレスポンスで、application/vnd.api+jsonメディアタイプを指定してこのヘッダーを使用しなければなりません。リクエストがapplication/vnd.api+json(またはサーバーがサポートする他の登録済みメディアタイプ)以外のContent-Typeを指定し、ボディを含む場合、サーバーは415 Unsupported Media Typeステータスで応答しなければなりません。リクエストがContent-Type: application/vnd.api+jsonを指定しているにもかかわらず、ボディが有効なJSON:APIドキュメントでない場合、サーバーは400 Bad Requestで応答しなければなりません。

サーバーは、標準的なコンテンツネゴシエーションを通じて、application/vnd.api+jsonと並行して他のメディアタイプをサポートできます。

データの取得:リソースとコレクションの取得

JSON:APIは、クライアントが必要なデータを正確に取得するための堅牢なメカニズムを提供します。

個別のリソースの取得

単一のリソースを取得するには、クライアントはそのリソースを表すエンドポイントにGETリクエストを送信します。

リクエスト:

GET /articles/1

Accept: application/vnd.api+json

成功レスポンス(200 OK):JSON

{
  "links": {
    "self": "/articles/1"
  },
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON:API Rocks!"
    }
    // ... 他の属性とリレーションシップ
  }
}

リソースが存在しない場合、サーバーは404 Not Foundを返すべきです。to-one関連リソースリンクが取得され、リレーションシップが空の場合、プライマリデータはnullになります。

リソースコレクションの取得

リソースのコレクションを取得するには、クライアントはそのコレクションを表すエンドポイントにGETリクエストを送信します。

リクエスト:

GET /articles

Accept: application/vnd.api+json

成功レスポンス(200 OK):JSON

{
  "links": {
    "self": "/articles",
    "next": "/articles?page[offset]=10",
    "last": "/articles?page[offset]=50"
  },
  "data": [
    {
      "type": "articles",
      "id": "1",
      "attributes": { "title": "Article 1" }
      // ...
    },
    {
      "type": "articles",
      "id": "2",
      "attributes": { "title": "Article 2" }
      // ...
    }
    // ... 他の記事
  ]
}

コレクションが空の場合、dataメンバーは空の配列[]になります。

リレーションシップ:リソースの接続

リレーションシップは、ほとんどのデータモデルの基本的な部分です。JSON:APIは、それらを定義し操作するための明確な方法を提供します。

リレーションシップの表現

リレーションシップは、リソースのrelationshipsオブジェクト内で定義されます。relationshipsオブジェクト内の各エントリは、個別のリレーションシップを表します(例:「author」、「comments」)。

リレーションシップオブジェクトは、以下の少なくとも1つを含まなければなりません。

  • linksselfおよびrelatedリンクを含みます。
  • selfリンク(リレーションシップURL)は、リレーションシップ自体の操作(例:to-manyリレーションシップでの項目の追加/削除)を可能にします。取得されると、関連リソースのリソース識別子オブジェクトを返します。
  • relatedリンク(関連リソースURL)は、関連リソースオブジェクトを直接取得することを可能にします。
  • data:リソースリンケージ(リソース識別子オブジェクト)を含みます。
  • to-oneリレーションシップの場合:単一のリソース識別子オブジェクトまたはnull
  • to-manyリレーションシップの場合:リソース識別子オブジェクトの配列または空の配列[]
  • meta:リレーションシップに関する非標準情報のためのメタオブジェクト。

「author」(to-one)および「comments」(to-many)リレーションシップの例:JSON

"relationships": {
  "author": {
    "links": {
      "self": "/articles/1/relationships/author",
      "related": "/articles/1/author"
    },
    "data": { "type": "users", "id": "42" }
  },
  "comments": {
    "links": {
      "self": "/articles/1/relationships/comments",
      "related": "/articles/1/comments"
    },
    "data": [
      { "type": "comments", "id": "5" },
      { "type": "comments", "id": "12" }
    ]
  }
}

リレーションシップの取得

クライアントは、提供されたリンクを使用して、リレーションシップ自体または関連リソースに関する情報を取得できます。

リレーションシップリンケージの取得(selfリンク):

GET /articles/1/relationships/comments

Accept: application/vnd.api+json

これは、記事「1」に関連するコメントのリソース識別子オブジェクトのコレクションを返します。

関連リソースの取得(relatedリンク):

GET /articles/1/comments

Accept: application/vnd.api+json

これは、記事「1」に関連する完全なコメントリソースオブジェクトのコレクションを返します。

データ取得の最適化

JSON:APIは、データ取得方法を最適化し、帯域幅を最小限に抑え、クライアント側のパフォーマンスを向上させるためのいくつかの機能を提供します。

複合ドキュメント:includeによるHTTPリクエストの削減

関連リソースを取得するためにサーバーへの複数回の往復を避けるために、JSON:APIではクライアントがincludeクエリパラメータを使用して関連リソースをプライマリレスポンスに含めるように要求できます。サーバーはこれらのリソースをトップレベルのincluded配列にサイドロードします。

記事を取得し、その著者とコメントを含めるリクエスト:

GET /articles/1?include=author,comments

Accept: application/vnd.api+json

レスポンス(200 OK):JSON

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": { "title": "..." },
    "relationships": {
      "author": {
        "data": { "type": "users", "id": "42" }
      },
      "comments": {
        "data": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    }
  },
  "included": [
    {
      "type": "users",
      "id": "42",
      "attributes": { "name": "John Doe" }
    },
    {
      "type": "comments",
      "id": "5",
      "attributes": { "body": "Great article!" }
    },
    {
      "type": "comments",
      "id": "12",
      "attributes": { "body": "Very informative." }
    }
  ]
}
  • includeパラメータは、リレーションシップパスのカンマ区切りリストを受け取ります。
  • ネストされたリレーションシップは、ドット記法(例:include=comments.author)を使用して含めることができます。
  • エンドポイントがincludeをサポートしていない場合、400 Bad Requestを返さなければなりません。
  • サーバーは、要求されていないリソースをincludedセクションに含めてはなりません。

スパースフィールドセット:必要なフィールドのみの取得

クライアントは、fields[TYPE]クエリパラメータを使用して、特定のタイプのリソースに対して特定のフィールド(属性とリレーションシップ)のみを返すように要求できます。これによりペイロードサイズが削減されます。

記事を取得するが、そのタイトルと著者リレーションシップのみを取得するリクエスト:

GET /articles?fields[articles]=title,author

Accept: application/vnd.api+json

レスポンス(200 OK):JSON

{
  "data": [
    {
      "type": "articles",
      "id": "1",
      "attributes": {
        "title": "Article 1"
      },
      "relationships": {
        "author": {
          "data": { "type": "users", "id": "42" }
        }
      }
    }
    // ... タイトルと著者のみを持つ他の記事
  ]
}
  • idtypeは常に含まれます。
  • クライアントが存在しないフィールドを要求した場合、サーバーはそれを無視しなければなりません。
  • クライアントがリレーションシップであるフィールドのみを要求した場合、attributesメンバーは省略されることがあります。

ソート

クライアントは、sortクエリパラメータを使用してプライマリデータをソートするように要求できます。

作成日(降順)、次にタイトル(昇順)でソートされた記事を取得するリクエスト:

GET /articles?sort=-created_at,title

Accept: application/vnd.api+json

  • 先頭のハイフン(-)は降順を示します。それ以外の場合は昇順です。
  • サーバーは、ソートに使用できる属性を定義します。サポートされていない属性でのソート要求は、400 Bad Requestになるべきです。

ページネーション

JSON:APIは様々なページネーション戦略をサポートしています。仕様では、ページネーションリンク(firstprevnextlast)がトップレベルのlinksオブジェクトにどのように表示されるべきかを定義しています。実際のページネーション戦略(例:ページベース、オフセットベース、カーソルベース)は、page[number]page[size]page[offset]page[limit]、またはpage[cursor]のようなクエリパラメータを使用してサーバーによって決定されます。

ページベースのページネーションリンクの例:JSON

"links": {
  "self": "/articles?page[number]=2&page[size]=10",
  "first": "/articles?page[number]=1&page[size]=10",
  "prev": "/articles?page[number]=1&page[size]=10",
  "next": "/articles?page[number]=3&page[size]=10",
  "last": "/articles?page[number]=5&page[size]=10"
}

クライアントは、独自のページネーションURLを構築するのではなく、提供されたこれらのリンクを使用すべきです。

フィルタリング

仕様では、データのフィルタリングのためにfilterクエリパラメータを予約しています。しかし、特定のフィルタリング戦略を義務付けてはいません。サーバーは、filter[attribute]=valueのような戦略や、より複雑な式ベースのフィルタリングなど、任意の戦略を実装できます。

例(JSON:APIによって推奨されていますが、義務付けられていません):

GET /comments?filter[post]=1 (ID 1の投稿のコメントを取得)

GET /comments?filter[post]=1,2&filter[author]=12 (投稿1または2のコメントを、著者12によって取得)

クライアントは、APIのドキュメントを参照して、その特定のフィルタリング機能について理解すべきです。

データの変更:リソースの作成、更新、削除

JSON:APIは、データ操作のための明確なプロトコルを定義しています。

リソースの作成

リソースを作成するには、クライアントはリソースのコレクションを表すURLにPOSTリクエストを送信します。リクエストボディは、type、およびオプションでattributesrelationshipsを含む単一のリソースオブジェクトを含まなければなりません。クライアントは、新しいリソースのidを提供してはなりません(クライアント生成IDがサポートされ有効になっている場合を除く)。

リクエスト:

POST /articles

Accept: application/vnd.api+json

Content-Type: application/vnd.api+jsonJSON

{
  "data": {
    "type": "articles",
    "attributes": {
      "title": "New Article Title",
      "body": "Content of the new article."
    },
    "relationships": {
      "author": {
        "data": { "type": "users", "id": "42" }
      }
    }
  }
}

成功レスポンス:

  • 201 Created:リソースが正常に作成された場合。レスポンスには、新しく作成されたリソースのURLを識別するLocationヘッダーを含まなければなりません。レスポンスボディには、サーバーによって割り当てられたidを含む、新しく作成されたリソースを含めるべきです。
  • 202 Accepted:作成リクエストが処理のために受け入れられたが、処理がまだ完了していない場合(例:非同期操作の場合)。レスポンスには、ステータスを監視するためのリンクが含まれる場合があります。
  • 204 No Content:リソースが正常に作成されたが、サーバーがレスポンスボディにリソース表現を返さないことを選択した場合。Locationヘッダーは引き続き必要です。

既に存在するクライアント生成IDを持つリソースを作成しようとした場合、かつサーバーがPOSTによる更新をサポートしていない場合、409 Conflictを返さなければなりません。

リソースの更新

リソースはPATCH HTTPメソッドを使用して更新されます。リクエストには、更新するリソースのidを含まなければなりません。リクエストボディには、typeid、および更新するattributesおよび/またはrelationshipsを含むリソースオブジェクトが含まれます。

記事のタイトルとそのリレーションシップの1つを更新するリクエスト:

PATCH /articles/1

Accept: application/vnd.api+json

Content-Type: application/vnd.api+jsonJSON

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "Updated Article Title"
    },
    "relationships": {
      "tags": {
        "data": [
          { "type": "tags", "id": "3" },
          { "type": "tags", "id": "4" }
        ]
      }
    }
  }
}

更新の重要なポイント:

  • 部分更新: PATCHリクエストは部分的なものにすべきです。リクエストに存在するフィールドのみが更新されるべきです。含まれていないフィールドは変更されないままにすべきです。
  • リレーションシップの更新:
  • To-one:リレーションシップのdataにリソース識別子オブジェクトまたはnullを提供します。
  • To-many:リソース識別子オブジェクトの配列を提供します。これは既存のリレーションシップメンバーを完全に置き換えます。セット全体を置き換えることなくメンバーを追加または削除するには、専用のリレーションシップエンドポイント(/articles/1/relationships/tags)をPOST(追加)、DELETE(削除)、またはPATCH(すべて置き換え)と共に使用すべきです。
  • サーバーは、リクエストで指定されていない属性またはリレーションシップを更新してはなりません。

成功レスポンス:

  • 200 OK:更新が成功し、サーバーが更新されたリソースの表現を返す場合。
  • 202 Accepted:更新リクエストが処理のために受け入れられたが、まだ完了していない場合。
  • 204 No Content:更新が成功したが、サーバーが表現を返さないことを選択した場合。

更新するリソースが存在しない場合、サーバーは404 Not Foundを返さなければなりません。

リレーションシップの直接更新

JSON:APIは、プライマリリソースの属性に影響を与えることなくリレーションシップを管理する特定の方法を提供します。

  • To-Oneリレーションシップの更新:PATCH /articles/1/relationships/authorContent-Type: application/vnd.api+jsonJSON
{
  "data": { "type": "users", "id": "24" } // 新しい著者を割り当てるか、nullにしてクリアする
}
  • To-Manyリレーションシップの更新(完全な置き換え):PATCH /articles/1/relationships/commentsContent-Type: application/vnd.api+jsonJSON
{
  "data": [
    { "type": "comments", "id": "101" },
    { "type": "comments", "id": "102" }
  ]
}
  • To-Manyリレーションシップへの追加:POST /articles/1/relationships/commentsContent-Type: application/vnd.api+jsonJSON
{
  "data": [
    { "type": "comments", "id": "103" }
  ]
}
  • To-Manyリレーションシップからの削除:DELETE /articles/1/relationships/commentsContent-Type: application/vnd.api+jsonJSON
{
  "data": [
    { "type": "comments", "id": "5" }
  ]
}

リレーションシップの更新が成功した場合、通常は200 OKまたは204 No Contentを返します。

リソースの削除

リソースを削除するには、クライアントはそのリソースのエンドポイントにDELETEリクエストを送信します。

リクエスト:

DELETE /articles/1

Accept: application/vnd.api+json

成功レスポンス:

  • 204 No Content:削除が成功し、レスポンスボディが返されない場合。
  • 200 OK:サーバーが削除に関するメタ情報を返す場合。
  • 202 Accepted:削除リクエストが処理のために受け入れられた場合。

リソースが存在しない場合、サーバーは404 Not Foundを返すべきです。仕様は、削除時に関連リソースやリレーションシップがどのように処理されるべきか(例:カスケード削除)を規定していません。これは実装の詳細です。

エラー処理

エラーが発生した場合、サーバーは適切なHTTPステータスコード(クライアントエラーには4xx、サーバーエラーには5xx)を使用しなければなりません。レスポンスボディにはJSON:APIエラードキュメントを含めるべきです。

エラードキュメントにはトップレベルのerrorsメンバーが含まれます。これはエラーオブジェクトの配列です。各エラーオブジェクトは以下を含むことができます。

  • id:この特定の問題発生に対する一意の識別子。
  • links:以下を含むリンクオブジェクト。
  • about:この特定の問題発生に関するさらなる詳細に繋がるリンク。
  • type:この特定のエラーがどのタイプのエラーのインスタンスであるかを識別するリンク。
  • status:この問題に適用されるHTTPステータスコード。文字列で表現されます。
  • code:アプリケーション固有のエラーコード。文字列で表現されます。
  • title:問題の短い、人間が読める要約。
  • detail:この特定の問題発生に固有の、人間が読める説明。
  • source:リクエストドキュメント内のエラーの原因への参照を含むオブジェクト。
  • pointer:リクエストドキュメント内の関連エンティティへのJSON Pointer [RFC6901]。
  • parameter:どのURIクエリパラメータがエラーを引き起こしたかを示す文字列。
  • header:エラーを引き起こした単一のリクエストヘッダーの名前を示す文字列。
  • meta:エラーに関する非標準のメタ情報を含むメタオブジェクト。

エラーレスポンスの例(422 Unprocessable Entity):JSON

{
  "errors": [
    {
      "status": "422",
      "source": { "pointer": "/data/attributes/email" },
      "title": "Invalid Attribute",
      "detail": "The email address is not valid."
    },
    {
      "status": "422",
      "source": { "pointer": "/data/relationships/author" },
      "title": "Invalid Relationship Value",
      "detail": "Author with ID '999' does not exist."
    }
  ]
}

サーバー側の考慮事項とベストプラクティス

コア仕様は包括的ですが、JSON:APIはURL設計やメンバー命名などの側面についても推奨事項を提供しています。

URL設計

  • リソースコレクションには複数形の名詞を使用します(例:/articles)。
  • 個別のリソースには/articles/{id}を使用します。
  • リレーションシップのセルフリンクには/articles/{id}/relationships/{relationshipName}を使用します。
  • 関連リソースリンクには/articles/{id}/{relationshipName}を使用します。

メンバー命名

  • メンバー名(キー)はキャメルケース(例:firstName)にすべきか、単語の区切りとしてハイフン/アンダースコアを使用すべきです(例:first-nameまたはfirst_name)。API内での一貫性が重要です。仕様自体は、独自のクエリパラメータにケバブケースを使用しています(例:page[number])。
  • メンバー名には、ASCII英数字、ハイフン、およびアンダースコアのみを含めるべきです。

仕様の拡張:拡張機能とプロファイル

JSON:APIは、進化するニーズと特定のユースケースに対応するために拡張可能に設計されています。

拡張機能

拡張機能は、基本仕様でカバーされていない新しい機能を追加できます。例としては、「Atomic Operations」拡張機能があり、単一のアトミックなリクエストで複数の操作(作成、更新、削除)を実行できます。クライアントとサーバーの両方が拡張機能を理解している場合にのみ使用できます。サーバーがサポートされていない拡張機能を含むリクエストを受け取った場合、適切なエラーで応答しなければなりません。

プロファイル

プロファイルは、特定のユースケース(例:タイムスタンプの特定の処理方法や、共通のmeta属性セット)のために、基本仕様の上に一連の規約を定義します。拡張機能とは異なり、プロファイルは一方の当事者によって理解されていなくても安全に無視できます。これらは、コア仕様への変更を必要とせず、普遍的なサポートを義務付けることなく、一般的なパターンの相互運用性を促進することを目的としています。

サーバーは、サポートされている拡張機能とプロファイルをトップレベルのjsonapiオブジェクトで宣伝できます。これにより、クライアントはこれらの機能を検出し、それに応じてリクエストを調整できます。

JSON:APIの未来

JSON:APIは、コミュニティの意見と新たなAPI設計の課題に対処する必要性に牽引され、進化を続けています。設定よりも規約、効率、開発者エクスペリエンスへの焦点は、最新のAPI構築における主要な標準としての地位を確立しています。JSON:APIを採用することで、開発チームは曖昧さを大幅に削減し、相互運用性を向上させ、APIの開発と利用のペースを加速させることができます。

この詳細な探求は、JSON:API仕様の大部分を網羅しています。これらの原則を理解し実装することで、開発者は機能的であるだけでなく、クリーンで一貫性があり、作業しやすいAPIを作成でき、最終的にはより生産的で協力的なAPIエコシステムを育むことができます。