推奨事項
このセクションでは、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は、コレクションのURLにリソースのIDを追加することで形成できます。
たとえば、IDが"1"
の写真のURLは次のようになります。
/photos/1
リレーションシップURLと関連リソースURL
基本仕様で説明されているように、各リレーションシップに対して公開できるURLは2つあります。
-
「リレーションシップURL」 - リレーションシップ自体のURL。これは、リレーションシップの
links
オブジェクト内のself
キーで識別されます。このURLにより、クライアントはリレーションシップを直接操作できます。たとえば、people
リソース自体を削除せずに、post
からauthor
を削除できます。 -
「関連リソース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 NOTEでは、推奨される形式の概要を示しています。
非同期処理
リソースの作成が必要で、操作の完了に時間がかかる状況を考えてみましょう。
POST /photos HTTP/1.1
要求は、Content-Location
ヘッダーにリンクを付けて202 Accepted
ステータスを返す**べき**です。
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
ヘッダーを返し、クライアントが再度確認するまでの待機時間をクライアントに指示することができます。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"
}
}
}
ジョブプロセスが完了したら、要求はLocation
ヘッダーにリンクを付けて303 See other
ステータスを返す**べき**です。
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.dokyumento.jp/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.