mcpField
J
jsonapi

jsonapi

github.com/prowler-cloud開発15.1k125 回インストール今日更新
リポジトリ

jsonapi について

jsonapiは、JSON:APIエンドポイントの実装やレビュー向けのコーディングスキルです。ドキュメント構造、リソース、関係、エラー、クエリパラメーター、HTTPステータスコードの仕様ルールをまとめています。

主な機能

  1. 01レスポンスとリソース構造のルール
  2. 02Content-Typeと識別子の要件
  3. 03関係とincludeのガイダンス
  4. 04エラー形式とステータスコード
  5. 05クエリパラメーター検証ルール

活用シーン

  1. 01エンドポイントのJSON:API準拠確認
  2. 02関係更新リクエストの設計
  3. 03APIエラーとクエリ処理のレビュー

MCP 対応

Context7 MCPを使って、最新のJSON:API仕様を確認する方法を推奨しています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/prowler-cloud/prowler --skill jsonapi

インストール後、Claude Code で/jsonapiを入力して読み込まれたか確認します。

詳細

django-drf での使用

このスキルは仕様への準拠に重点を置いています。実装パターン(ViewSet、Serializer、Filter)については、このスキルとあわせて django-drf スキルを使用してください。

スキル対象
jsonapi仕様で要求される事項(MUST/MUST NOT のルール)
django-drfDRF での実装方法(コードパターン)

エンドポイントを作成または変更する際は、両方のスキルを呼び出してください。


実装/レビューの前に

エンドポイントを作成または変更する前に、必ず最新の仕様に照らして検証してください。

オプション 1:Context7 MCP(推奨)

Context7 MCP が利用可能な場合は、JSON:API 仕様を直接照会してください。

mcp_context7_resolve-library-id(query="jsonapi specification")
mcp_context7_query-docs(libraryId="<resolved-id>", query="[specific topic: relationships, errors, etc.]")
オプション 2:WebFetch(代替手段)

Context7 が利用できない場合は、公式仕様を取得してください。

WebFetch(url="https://jsonapi.org/format/", prompt="Extract rules for [specific topic]")

これにより、仕様が更新された後も、最新の JSON:API バージョンに準拠できます。


重要なルール(絶対に破らないでください)

ドキュメント構造
  • 同じレスポンスに data と errors を両方含めてはいけません
  • data、errors、meta のうち、少なくとも 1 つを必ず含めてください
  • リソースオブジェクトでは、必ず type と id(文字列)を使用してください
  • リソースを作成する際に id を含めてはいけません(サーバーが生成します)
Content-Type
  • 必ず Content-Type: application/vnd.api+json を使用してください
  • 必ず Accept: application/vnd.api+json を使用してください
  • ext/profile がない場合、メディアタイプにパラメーターを追加してはいけません
リソースオブジェクト
  • id には必ず文字列を使用してください(UUID の場合も同様です)
  • type には必ず小文字のケバブケースを使用してください
  • attributes の中に id や type を入れてはいけません
  • 外部キーを attributes に含めてはいけません。relationships を使用してください
リレーションシップ
  • links、data、meta のうち、少なくとも 1 つを必ず含めてください
  • 必ずリソースリンク形式 {"type": "...", "id": "..."} を使用してください
  • リレーションシップに生の ID を使用してはいけません。必ずリンクオブジェクトを使用してください
エラーオブジェクト
  • エラーは必ず配列として返してください:{"errors": [...]}
  • status は必ず文字列で含めてください(例:"400"。400 ではありません)
  • フィールド固有のエラーには、必ず source.pointer を含めてください

HTTP ステータスコード(必須)

操作成功非同期競合見つからない禁止不正なリクエスト
GET200--404403400
POST201202409404403400
PATCH200202409404403400
DELETE200/204202-404403-
使い分け
コード使用する場合
200 OKGET の成功、レスポンスボディを返す PATCH、レスポンスを返す DELETE
201 CreatedPOST でリソースを作成した場合(Location ヘッダーを必ず含めてください)
202 Accepted非同期操作を開始した場合(タスク参照を返してください)
204 No ContentDELETE の成功、またはレスポンスボディを返さない PATCH
400 Bad Requestクエリパラメーターが無効、不正なリクエスト、不明なフィールド
403 Forbidden認証は成功したものの権限がない場合、クライアント生成 ID が拒否された場合
404 Not Foundリソースが存在しない、または RLS により非表示の場合(どちらであるかを決して明かさないでください)
409 ConflictID の重複、type の不一致、リレーションシップの競合
415 UnsupportedContent-Type ヘッダーが誤っている場合

ドキュメント構造

成功レスポンス(単一)
{
  "data": {
    "type": "providers",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "attributes": {
      "alias": "Production",
      "connected": true
    },
    "relationships": {
      "tenant": {
        "data": {"type": "tenants", "id": "..."}
      }
    },
    "links": {
      "self": "/api/v1/providers/550e8400-..."
    }
  },
  "links": {
    "self": "/api/v1/providers/550e8400-..."
  }
}
成功レスポンス(リスト)
{
  "data": [
    {"type": "providers", "id": "...", "attributes": {...}},
    {"type": "providers", "id": "...", "attributes": {...}}
  ],
  "links": {
    "self": "/api/v1/providers?page[number]=1",
    "first": "/api/v1/providers?page[number]=1",
    "last": "/api/v1/providers?page[number]=5",
    "prev": null,
    "next": "/api/v1/providers?page[number]=2"
  },
  "meta": {
    "pagination": {"count": 100, "pages": 5}
  }
}
エラーレスポンス
{
  "errors": [
    {
      "status": "400",
      "code": "invalid",
      "title": "Invalid attribute",
      "detail": "UID must be 12 digits for AWS accounts",
      "source": {"pointer": "/data/attributes/uid"}
    }
  ]
}

クエリパラメーター

ファミリー形式例
pagepage[number]、page[size]?page[number]=2&page[size]=25
filterfilter[field]、filter[field__op]?filter[status]=FAIL
sortカンマ区切り、降順には -?sort=-inserted_at,name
fieldsfields[type]?fields[providers]=id,alias
includeカンマ区切りのパス?include=provider,scan.task
ルール
  • サポートされていないクエリパラメーターには、400 を必ず返してください
  • サポートされていない include パスには、400 を必ず返してください
  • サポートされていない sort フィールドには、400 を必ず返してください
  • fields[type] が指定されている場合、追加のフィールドを含めてはいけません

よくある違反(避けてください)

違反誤り正しい例
ID が整数"id": 123"id": "123"
type が camelCase"type": "providerGroup""type": "provider-groups"
外部キーが attributes 内にある"tenant_id": "...""relationships": {"tenant": {...}}
エラーが配列ではない{"error": "..."}{"errors": [{"detail": "..."}]}
status が数値"status": 400"status": "400"
data と errors の併記{"data": ..., "errors": ...}いずれか一方のみ
pointer がない{"detail": "Invalid"}{"detail": "...", "source": {"pointer": "..."}}

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

単一リレーションシップ
PATCH /api/v1/providers/123/relationships/tenant
Content-Type: application/vnd.api+json

{"data": {"type": "tenants", "id": "456"}}

クリアする場合:{"data": null}

複数リレーションシップ
操作メソッド本文
すべて置き換えるPATCH{"data": [{...}, {...}]}
メンバーを追加するPOST{"data": [{...}]}
メンバーを削除するDELETE{"data": [{...}]}

複合ドキュメント(include)

?include=provider を使用する場合:

{
  "data": {
    "type": "scans",
    "id": "...",
    "relationships": {
      "provider": {
        "data": {"type": "providers", "id": "prov-123"}
      }
    }
  },
  "included": [
    {
      "type": "providers",
      "id": "prov-123",
      "attributes": {"alias": "Production"}
    }
  ]
}
ルール
  • 含めるすべてのリソースは、プライマリデータからリレーションシップの連鎖をたどって到達できなければなりません
  • 孤立したリソースを含めてはなりません
  • リソースを重複して含めてはなりません(同じ type+id)

仕様の参照先

  • 仕様全文:https://jsonapi.org/format/
  • 実装:DRF 固有のパターンには django-drf スキルを使用します
  • テスト:テストパターンには prowler-test-api スキルを使用します

コメント