Claude Media
Claude CodeでPrismのモックサーバーを立てる — 仕様先行でフロントを進める

Claude CodeでPrismのモックサーバーを立てる — 仕様先行でフロントを進める

OpenAPI定義からPrismのモックサーバーを立て、examplesで異常系の返り値を固定し、フロントの実装をClaude Codeに進めさせる手順と設定をまとめます。

バックエンドが未完成でも、OpenAPI定義があればフロントの実装は始められます。Prismは、OpenAPI定義から動くモックサーバーを立てるオープンソースのCLIです。ここにClaude Codeのフロント実装をつなぐと、実APIを待たずに画面と通信処理を進められます。

この記事では、Prismの起動から、異常系の返り値をexamplesで固定する書き方、Claude Codeに渡す設定とプロンプトまでを手順にします。モックの前提になる定義そのものの検査は、SpectralでOpenAPIをlintする構成が先に効きます。

Prismのモックでフロント側が先に確かめられること

Prismは、OpenAPI v2、v3.0、v3.1とPostman Collectionsを入力にして、モックサーバーと検証プロキシを提供します。モックの狙いは、API定義の段階で「クライアントが必要とするデータが含まれているか」「形式が使いやすいか」を確かめ、本番APIを作ってから直す手戻りを避けることです。

Claude Codeにとっての利点は、フロントの実装が「実在しないAPIを想像で呼ぶ」状態を抜け出す点にあります。リクエストの形は定義が決め、レスポンスはモックが返します。型が合わなければPrismが指摘するので、実装の正しさを機械が判定します。

起動する — インストールからフロントの接続先まで

Node.js 18.20.1以上の環境なら、npmでグローバルに入れます。Node.jsが無い環境向けには、スタンドアロンのバイナリとDockerイメージも用意されています。

npm install -g @stoplight/prism-cli
prism mock openapi.yaml

起動すると、定義にある操作の一覧と待ち受けURLが出ます。既定はhttp://127.0.0.1:4010です。

✔  success   Prism is listening on http://127.0.0.1:4010
●  note      GET        http://127.0.0.1:4010/pets
●  note      POST       http://127.0.0.1:4010/pets

フロントの開発サーバーが向けるAPI_BASE_URLをこのURLにします。ここで一つ、つまずきやすい点があります。OpenAPI v3ではservers[].urlにベースパスが含まれます。定義側のベースパスがapi/v1、パスがhelloなら、モックへのリクエストはhttp://localhost:4010/helloです。/api/v1/helloを叩くと失敗します。Prism起動時の出力で、実際のURLを必ず見てください。

Dockerで動かす場合は、コンテナの外から届くようにホストを0.0.0.0にします。

docker run --init --rm -v $(pwd):/tmp -p 4010:4010 \
  stoplight/prism:4 mock -h 0.0.0.0 "/tmp/openapi.yaml"

Prismは読み込んだ定義ファイルの変更を監視し、変わるとHTTPサーバーを自動で再起動します。Claude Codeが定義を編集しても、手動で止めて起動し直す必要はありません。ただし、操作が1つも無い定義に書き換えた場合は再起動されず、直前の内容で配信を続けます。

異常系の返り値をexamplesで固定する

Prismの応答は、定義の中の情報から決まります。既定は静的生成で、レスポンスにexampleがあればそれを返し、無ければスキーマから値を作ります。プロパティにexampleもdefaultも無い文字列は"string"、数値は0になります。

異常系をフロントで確かめたいなら、定義に異常系のレスポンスとexampleを書きます。ここがClaude Codeに書き足させる作業の中心です。次は、在庫APIの例です(説明用に作った定義で、公式のサンプルではありません)。

paths:
  /items/{id}:
    get:
      operationId: getItem
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: integer }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Item' }
              examples:
                normal:
                  value: { id: 1, name: "ノート", stock: 12 }
                soldOut:
                  value: { id: 2, name: "ペン", stock: 0 }
        '404':
          description: 商品が存在しない
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Error' }
              examples:
                notFound:
                  value: { code: "ITEM_NOT_FOUND", message: "商品が見つかりません" }

このように複数のexampleに名前を付けておくと、リクエストごとに返り値を選べます。選び方はPreferヘッダーかクエリで指定します。クエリで指定するときは、キー名の前に二重アンダースコアを付けます。

指定ヘッダーの形クエリの形効果
ステータスの固定ヘッダーの形Prefer: code=404クエリの形__code=404効果そのステータスのレスポンスを返す
exampleの選択ヘッダーの形Prefer: example=soldOutクエリの形__example=soldOut効果名前で例を選ぶ
動的生成の切替ヘッダーの形Prefer: dynamic=falseクエリの形__dynamic=false効果起動時の-dを上書きする

三つは組み合わせられます。注意点は、codeを付けないとPrismは200系のレスポンスからだけexampleを探すことです。404の例を選ぶならcode=404とセットで指定します。

curl -s "http://127.0.0.1:4010/items/2" -H "Prefer: example=soldOut"
curl -s "http://127.0.0.1:4010/items/9" -H "Prefer: code=404, example=notFound"

公式のガイドは、exampleを置くレスポンスのステータスを明示しておくよう勧めています。Prismが検証違反などを理由にステータスを変えると、置いたexampleが使われないことがあるためです。

契約違反はモックが422で返す

モックは返すだけでなく、リクエストも検証します。型、形式、必須項目といった定義の規則に合わない呼び出しには、次の順でレスポンスを選びます。

  1. その操作に422のレスポンスが定義されていれば、それを返す
  2. 無ければ400の定義を探す
  3. どちらも無ければ、Prismがapplication/problem+json形式の422を自動生成する

自動生成される本文には、validation配列に違反の内容が入ります。必須のnameが欠けたPOSTなら、should have required property 'name'のようなメッセージがlocation: ["body"]付きで返ります。フロントの送信処理が定義とずれているとき、Claude Codeはこの本文を読んで直せます。

自前の422を返したいときは、定義に422のレスポンスとexampleを書きます。フロントのバリデーション表示を確かめる素材にもなります。

--errorsフラグには注意してください。公式のCLIガイドでこのフラグが登場するのは、prism proxyの節です。プロキシで実APIとの食い違いを検出し、違反をRFC 7807形式のエラーに変える用途で、実装が出来上がった後の契約テストに回します。モックの段階ではこのフラグは不要で、上の自動生成が働きます。

Claude Codeに進めさせる設定

ここまでの内容を、Claude Codeが毎回守れる形に落とします。置く場所は3つです。

CLAUDE.mdに接続先と作法を書く

CLAUDE.mdは、Claude Codeがセッションの開始時に読む指示ファイルです。モックの前提を書いておくと、毎回の説明が要りません。

## モックAPI
- 仕様は `openapi.yaml`。モックは別ターミナルで `prism mock openapi.yaml` を起動済みとする(待ち受け: http://127.0.0.1:4010)
- フロントのAPI呼び出しは `API_BASE_URL` 経由にし、URLを直書きしない
- 異常系の確認は `Prefer: code=<ステータス>, example=<名前>` ヘッダーで行う
- 新しい異常系が必要なら、コードではなく `openapi.yaml` の examples に先に書く
- 422が返ったら、レスポンスの `validation` 配列を読んで送信側を直す。定義は勝手に緩めない

最後の2行が要点です。モックの応答がおかしいときに、Claude Codeが定義の側を変えて辻褄を合わせると、仕様先行の意味が崩れます。定義の変更は人が確認するものとして、書いておきます。

権限は必要なコマンドだけ許可する

curlでモックを叩く確認を毎回承認していては進みません。設定に許可ルールを足します。プレフィックス一致は、*の前にスペースを入れたBash(curl *)の形で書きます。

{
  "permissions": {
    "allow": [
      "Bash(curl http://127.0.0.1:4010/*)",
      "Bash(npm run *)"
    ]
  }
}

curl *と広く許可すると外部への通信も通るので、モックのURLに絞っています。Prism自体は起動したままにする常駐プロセスなので、開発者が別ターミナルで立てておく運用が単純です。

examplesの書き足しを頼む

異常系を足す作業は、定義への追記として指示します。たとえば、次のように頼みます。

openapi.yaml の getItem に、404 と 422 のレスポンスを追加して。
Error スキーマを $ref で使い、examples に notFound と invalidId を名前付きで置く。
追加後、curl で Prefer ヘッダーを使って各例が返ることを確認して。

Claude Codeが追記すると、Prismは自動で再起動するので、そのままcurlで確かめられます。ここまでを非対話で回したいなら、claude -pが使えます。

claude -p "openapi.yaml の getItem に404のexampleを追加して" \
  --allowedTools "Read,Edit"

--allowedToolsに並べたツールは、承認なしで使われます。ReadとEditだけにすれば、定義の編集は進み、コマンド実行は許可されません。

実装を進めさせる順序

モックがあると、フロントの実装は次の順に切れます。

  1. 正常系の画面を、200のexampleで組む
  2. 空、在庫切れなどの例をexample=で切り替えて、表示を確かめる
  3. 404と422の例を足し、エラー表示を組む
  4. 動的生成(-d)に切り替え、想定外に長い値やゼロでも崩れないかを見る

4番目は、Prismの動的モードの役割です。-dを付けると、型やformatに沿ったランダム値を返します。同じ値だけを相手にしていると、名前が想定より長い場合や数値が0の場合を見落とします。x-fakerキーでFakerのメソッドを指定すれば、生成値を人名やURLの形に寄せられます。動的モードは起動時に-dで決め、リクエスト単位ではPrefer: dynamic=trueで切り替えられます。

実装ができたらproxyで定義と突き合わせる

バックエンドが動き出したら、接続先をモックから検証プロキシに切り替えます。prism proxyは、リクエストを実APIへ中継しながら、行き来する内容を定義と照らします。

prism proxy openapi.yaml http://localhost:8080 --errors

違反は標準出力と、レスポンスのsl-violationsヘッダーに出ます。--errorsを付けると、違反のあるリクエストやレスポンスがRFC 7807形式のエラーに変わり、フロントの動作確認でも見逃しません。付けない場合は、違反を記録するだけで実APIの応答をそのまま返します。モックで固めた異常系の例が、実APIでも同じ形で返るかを見る段階です。Claude Codeには「sl-violationsに出た違反を、実装と定義のどちらが誤りか切り分けて報告して」と頼むと、定義を勝手に直す動きを避けられます。

Docker Composeで開発環境に組み込むなら、stoplight/prism:4イメージにコマンドを渡す形で書きます。commandのmock -h 0.0.0.0と、定義ファイルを読み取り専用で載せるvolumes、ポートの割り当てがあれば動きます。

つまずきやすい点

  • 循環参照のある定義は、CLIがモックの起動自体を拒否します。再帰的なスキーマを$refで作らせないよう、定義の側で避けます
  • パスは定義に書かれた順に評価されます。/items/{id}と/items/searchのように重なるパスは、具体的な方を先に書きます
  • deprecated: trueの操作には、レスポンスにDeprecation: trueヘッダーが付きます。フロントが非推奨APIを使っていないかの目印になります
  • --ignoreExamplesを付けた静的モードは、exampleを無視してPrismの作る値を返します。異常系のexampleが効かないと感じたら、起動オプションを疑います
  • 複数のサーバーを持つ定義では、__serverクエリで指定先が定義に含まれるかを検証できます。含まれないと404が返ります

まとめ

Prismのモックは、定義に書いたものしか返しません。だからこそ、異常系の返り値を決める作業が、コードではなくexamplesへの追記になります。Claude Codeには、定義を勝手に緩めないこと、確認はPreferヘッダーで行うことを渡しておくと、フロントの実装だけを進められます。

モックの先は、実装との照合です。生成したクライアントを固定する流れはOpenAPI Generatorを使う設定に、定義そのものの監査は42Crunchプラグインの手順につながります。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. github.com/stoplightio/prism
  2. github.com/stoplightio/prism/blob/master/docs/guides/01-mocking.md
  3. github.com/stoplightio/prism/blob/master/docs/guides/02-request-valid…
  4. github.com/stoplightio/prism/blob/master/docs/getting-started/03-cli.…
  5. code.claude.com/docs/en/headless
  6. code.claude.com/docs/en/permissions
  7. code.claude.com/docs/en/memory
この記事を共有:XはてブLinkedIn