every Tech Blog

株式会社エブリーのTech Blogです。

CursorにAPI仕様書を作成させてみた

はじめに

こんにちは、エブリーでサーバーサイドをメインに担当している清水です。
私の所属する小売アプリチームでは他社から事業譲渡という形で引き継がれた小売店様向けのシステムの保守運用を行っております。

引き継いだシステムについて

  • PHP, Laravelで開発されており、MVCにService層とRepository層を加えた形で設計されています
  • APIエンドポイントが100個以上
  • 外部API連携有り
  • 数年以上運用している

事業譲渡で引き継いだシステムの保守運用における課題

事業譲渡のタイミングで様々な資料を引き継いでいるのですが、いくつかの資料は改修前の状態のまま残っているなど、不十分な状態です。
その結果、ジョインしたばかりのエンジニアが機能を把握しようとした際に、資料だけでは十分に理解できず、実際のコードを読み込まなければならないという高いハードルがあります。
本来であれば一度全てのコードを読み込み、最新の状態に合わせて資料を作り直すのが理想ですが、日々の保守運用タスクに追われる中で、そのような時間を確保することは難しいのが現状です。
私がこのチームにジョインして最初に困ったことは「どのエンドポイントでどのような処理が実行されるのか?」を把握することでした。
そこで、今回はCursorに最新の状態のAPI仕様書を簡単に作らせることができるかを検証してみたいと思います。

CursorにAPI仕様書を作成させる方針

以下のモデルを使用します

  • claude-4-sonnet-thinking
  • claude-3.7-sonnet-thinking
  • gemini-2.5-flash
  • claude-4-sonnet
  • claude-3.7-sonnet

私はほとんどの開発業務でclaude-4-sonnetを使用しているので、より廉価なclaude-3.7-sonnetと出力内容にどれくらい違いが発生するかを確かめたいと思います。
また、gemini-2.5-flashはコードリーディングで優れているという噂を耳にしたことがあるため、こちらも検証したいと思います。

期待する出力内容

  • markdownのテーブル形式
  • エンドポイント, リクエスト, レスポンス, 概要説明の4列

プロンプトを実行する上での前提

  • Cursor Rulesは何も設定しておりません
  • MCPとの通信は何も行っておりません

出力させるプロンプト内容

このシステムのAPI仕様書を作成してください。
# 期待する出力内容
- markdownのテーブル形式
- エンドポイント, リクエスト, レスポンス, 概要説明の4列

# 作成する方法
- routes/api.phpに記載される全てのエンドポイントを対象とする
- エンドポイント列にはエンドポイントのパスを記載すること(例: /auth/sign_in)
- RequestクラスはApp/{Domain}/Requestsに置かれています
- ResponseクラスはApp/{Domain}/Responseに置かれています
- いくつかのエンドポイントではRequestクラス、Responseクラスが使われていないものがあります。その場合はコントローラーの内容を見てAPI仕様書を作成してください。
- リクエスト列にはリクエストのBodyに含まれるキーとバリュー例を記載すること(例: {"id":"test", "password":"test"})
- レスポンス列にはレスポンスの内容を記載すること(例: {"access_token": "test","refresh_token": "test"})
    - 具体的なレスポンスの値は"test"などの適当なサンプル値を指定すること
    - 数字、文字列、配列、真偽値であることがわかるように表示すること
- 概要説明にはそのエンドポイントでどのような処理が行われているかを記載すること(例: リクエストに含まれるIDとパスワードを使用してログイン認証処理を行う)

出力内容(モデル毎)

claude-4-sonnet-thinking

エンドポイント リクエスト レスポンス 概要説明
POST /auth/token_refresh {"refresh_token": "refresh_test"} {"access_token": "new_access_test"} リフレッシュトークンを使用してアクセストークンを更新する
POST /auth/logout {} {"message": "success"} ログアウト処理を行い、認証情報を無効化する
POST /auth/login {"auth_code": "123456"} {"member_no": "test123", "access_token": "access_test", "refresh_token": "refresh_test"} SMS認証コードを使用してログイン認証処理を行う
POST /auth/auth_code/issue {"tel_no": "09012345678", "password": "test_password"} {} SMS認証コード発行処理を行う

claude-3.7-sonnet-thinking

エンドポイント リクエスト レスポンス 概要説明
POST /auth/token_refresh {"refresh_token": "test_refresh_token"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} リフレッシュトークンを使用して新しいアクセストークンを取得します
POST /auth/logout {} {"status": "success"} ユーザーをログアウトし、トークンを無効化します
POST /auth/login {"tel": "08012345678", "auth_code": "123456"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} SMS認証コードを使用してログインします
POST /auth/auth_code/issue {"tel": "08012345678"} {"status": "success"} ログイン用のSMS認証コードを発行します

gemini-2.5-flash

エンドポイント リクエスト レスポンス 概要説明
POST /auth/token_refresh {"refresh_token": "your_refresh_token"} {"access_token": "test_new_access_token"} リフレッシュトークンを使用して新しいアクセストークンを発行します。
POST /auth/logout {} (ヘッダーにAccess-Token: your_access_token) {"message": "success"} ユーザーのログアウト処理を実行し、アクセストークンを無効化します。
POST /auth/login {"auth_code": 123456} (ヘッダーにDevice-id: your_device_id) {"member_no": "test_member_no", "access_token": "test_access_token", "refresh_token": "test_refresh_token"} SMS認証コードを使用してログインを行い、認証が成功した場合に会員番号、アクセストークン、リフレッシュトークンを返却します。
POST /auth/auth_code/issue {"tel_no": "09012345678", "password": "your_password"} (ヘッダーにDevice-id: your_device_id) {} 電話番号とパスワードを使用してSMS認証コードを発行します。

claude-4-sonnet

エンドポイント リクエスト レスポンス 概要説明
POST /auth/token_refresh {"refresh_token": "test_refresh_token"} {"access_token": "test_new_access_token"} リフレッシュトークンを使用して新しいアクセストークンを取得する
POST /auth/logout {} {} ユーザーのログアウト処理を行いセッションを無効化する
POST /auth/login {"auth_code": "123456"} {"member_no": "123456", "access_token": "test_access_token", "refresh_token": "test_refresh_token"} SMS認証コードを使用してログイン認証処理を行う
POST /auth/auth_code/issue {"tel_no": "09012345678", "password": "test_password"} {} SMS認証コードを電話番号宛に発行する

claude-3.7-sonnet

エンドポイント リクエスト レスポンス 概要説明
POST /auth/token_refresh {"refresh_token": "test_refresh_token"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} リフレッシュトークンを使用してアクセストークンを更新する
POST /auth/logout {} {"message": "ログアウトしました"} ユーザーのログアウト処理を行う
POST /auth/login {"phone_number": "09012345678", "auth_code": "123456"} {"access_token": "test_token", "refresh_token": "test_refresh_token", "expires_in": 3600} SMS認証コードを使用したログイン認証処理を行う
POST /auth/auth_code/issue {"phone_number": "09012345678"} {"message": "認証コードを送信しました"} SMS認証コードを発行し、指定された電話番号に送信する

※全てのエンドポイントを出力させましたが、本記事に掲載する内容は一部分としています ※内容の一部をブログ用に実際のコードとは異なるものになるように手で修正してあります

プロンプトの調整が必要になった部分

  • 全てのモデルについて、Requestクラス、Responseクラスのディレクトリの位置を指定しないと必要なパラメーターが無視されたり、存在しないパラメーターが生み出されることがあった

出力内容について

  • claude-4-sonnet-thinking, gemini-2.5-flashは全て正確に出力されている
  • claude-3.7-sonnet, claude-3.7-sonnet-thinkingは共に存在しないレスポンスのパラメーターを出力してしまっている
  • claude-4-sonnetは概ね問題ないものの、/auth/logoutのレスポンスの{"message": "success"}だけ抜けてしまっている

おわりに

本記事では保守運用を行っているシステムのAPI仕様書をCursorで一から作成することを試みました。
結果として、claude-4-sonnet-thinking, gemini-2.5-flashについては完璧な内容が出力されるという結果となりました。
システムの内容やプロンプトの内容によって結果は変わるかと思いますが、API仕様書の作成・更新についてはCursorに任せても支障はなさそうに思えます。
また、今回はマークダウン形式のテーブルで出力しましたが、カンマ区切りのCSVとして出力させて、その内容を手動でExcelファイルに変換する。といった使い方をするなど様々な可能性がありそうです。
この記事がシステム開発における資料作成を行っている方の参考になれば幸いです。
最後までお読みいただきましてありがとうございました。