DEV Community

Cover image for APIをGitネイティブに設計・開発する方法
Akira
Akira

Posted on • Originally published at apidog.com

APIをGitネイティブに設計・開発する方法

ほとんどのAPIチームは、契約を後回しにしがちです。先にコードを書き、そこから仕様書を生成し、時間が経つにつれてコードと仕様が乖離していきます。GitネイティブAPIデザインでは、この順序を逆にします。API契約をソースコードとして扱い、Gitでバージョン管理し、アプリケーションコードと同じようにレビューします。

今すぐApidogを試す

このガイドでは、特定のツールではなく、Gitを中心にしたAPI設計の進め方を扱います。ブランチで契約を設計し、プルリクエストでレビューし、コミット済みの仕様からモック、テスト、ドキュメントを生成する流れを実装できるようにします。

Spec-Firstツールの概要や製品ウォークスルーを知りたい場合は、gitネイティブAPIワークフローに関する補足記事も参照してください。この記事では、実践的なワークフローに絞って説明します。

API作業における「Gitネイティブ」とは

Gitネイティブとは、API定義をプレーンテキストファイルとしてリポジトリに置くことです。独自のクラウドDBやベンダーUIの内部データではなく、コードの隣にある .yaml または .json ファイルを正とします。

たとえば、次のような構成です。

repo/
  api/
    openapi.yaml
  src/
    ...
  .github/
    workflows/
      api-lint.yml
Enter fullscreen mode Exit fullscreen mode

多くのAPIデザインツールでは、契約の正本がクラウド側にあります。Web UIで編集し、必要に応じて仕様をエクスポートする形です。この場合、Gitリポジトリに残るのは古いスナップショットになりがちで、Git履歴からAPIがどう進化したかを追跡できません。

Gitネイティブとクラウドツールの比較

Gitネイティブモデルでは、main ブランチ上の仕様ファイルが契約です。GUI、モック、ドキュメント、テストはすべて、そのファイルに対するビューまたは派生成果物として扱います。

GitネイティブなAPI設計には、次の3つの条件があります。

  1. 仕様がリポジトリ内のテキストファイルである
  2. 変更がブランチ、コミット、PR、マージを通じて進む
  3. モック、ドキュメント、テスト、クライアントがコミット済み仕様から生成される

APIをGitで設計・開発する理由

コードをGitで管理するなら、API契約も同じように管理すべきです。理由は実装上のメリットが大きいからです。

1. 履歴を追跡できる

「いつ cursor ページネーションを追加したのか?」という質問には、git log で答えられます。

git log -p -- api/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

該当コミットには、変更内容、作成者、日付、コミットメッセージが残ります。別の変更履歴ツールやスクリーンショットを探す必要はありません。

2. 責任範囲を確認できる

仕様ファイルに対して git blame を実行すると、誰がどの行を変更したかを確認できます。

git blame api/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

混乱を招くフィールド名やレスポンス定義があれば、それを追加したPRまで遡れます。設計判断の議論もPR上に残ります。

3. ロールバックできる

問題のあるAPI設計をマージしてしまった場合でも、Gitなら git revert で戻せます。

git revert <commit-sha>
Enter fullscreen mode Exit fullscreen mode

仕様が戻れば、そこから生成されるモック、ドキュメント、クライアント、テストも元の契約に戻せます。個別のツールで手動修正する必要はありません。

4. PRで設計レビューできる

API設計は、実装前にレビューするほど安く修正できます。PRでは、レビュー担当者が追加・削除された行に直接コメントできます。

+ /users/{userId}/invoices:
+   get:
+     operationId: listUserInvoices
Enter fullscreen mode Exit fullscreen mode

命名、ステータスコード、ページネーション、エラー形式などを、ハンドラーコードを書く前に合意できます。

単一の信頼できる情報源があることが重要です。契約が main の1ファイル、または管理された複数ファイルにあるなら、フロントエンド、バックエンド、QA、ドキュメント担当者が同じ定義を参照できます。これは、GitベースのAPI仕様ワークフローの中心的な価値です。

GitネイティブAPIデザインループ

GitネイティブなAPI設計は、次のループで進めます。

  1. 契約を設計する
  2. 仕様ファイルをコミットする
  3. PRを開く
  4. 設計レビューを行う
  5. マージ後に実装する

実装はマージ後です。コードが先ではありません。

例: 請求書一覧APIを追加する

ブランチを作成します。

git checkout -b feat/api-invoices-list
Enter fullscreen mode Exit fullscreen mode

openapi.yaml にエンドポイントを追加します。

# openapi.yaml
paths:
  /users/{userId}/invoices:
    get:
      operationId: listUserInvoices
      summary: ユーザーの請求書を一覧表示
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: status
          in: query
          required: false
          schema:
            type: string
            enum: [draft, open, paid, void]
      responses:
        "200":
          description: 請求書のページ
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceList"
        "404":
          description: ユーザーが見つかりません
Enter fullscreen mode Exit fullscreen mode

変更を小さくコミットします。

git add api/openapi.yaml
git commit -m "GET /users/{userId}/invoices 契約を追加"
Enter fullscreen mode Exit fullscreen mode

PRを開くと、レビュー担当者は次の点を確認できます。

  • パス名は既存APIと一貫しているか
  • operationId は明確か
  • status の enum は十分か
  • ページネーションが必要か
  • 404 は適切か
  • エラーレスポンス形式は既存APIと一致しているか

PRが承認されたら main にマージします。その後、バックエンド実装、フロントエンド開発、モック、テストを同じ契約に基づいて進めます。

これが スペックファーストAPI開発 の実践です。合意された契約が、実装より先に存在します。

API契約のブランチ戦略

API契約の変更も、通常のコード変更と同じように扱います。1つのPRには、1つの論理的な変更だけを含めます。

おすすめは、変更の種類が分かるブランチ名を使うことです。

変更の種類 ブランチプレフィックス レビューの重み
新しいエンドポイント feat/api- feat/api-invoices-list 標準
追加フィールド feat/api- feat/api-invoice-currency 軽い
破壊的変更 break/api- break/api-remove-legacy-id 重い、承認必須
仕様のバグ修正 fix/api- fix/api-status-enum-typo 軽い
リファクタリングのみ chore/api- chore/api-reorder-schemas 軽い

break/api- という名前は、レビュー担当者に「既存コンシューマへの影響を必ず確認する」ことを示します。chore/api- は意味的な変更がないことを示すため、レビュー負荷を下げられます。

トランクベースかGitflowか

API仕様には、短命ブランチを使うトランクベース開発が向いています。

モデル 最適なケース APIでのトレードオフ
トランクベース 継続的デリバリー、小規模〜中規模チーム 契約が小さく進化し、マージ競合が少ない
Gitflow スケジュールされたリリース、規制の強い環境 developrelease で仕様が分岐し、マージが大きくなりやすい

ほとんどのAPIチームでは、短命ブランチ + 小さなPRを推奨します。長期間のブランチでは、複数チームが同じYAMLを編集し、マージ競合が発生しやすくなります。

プルリクエストでのAPIデザインレビュー

仕様PRは構文チェックではなく、設計レビューです。レビューでは、少なくとも次の観点を確認します。

既存コンシューマを壊さないか

次の変更は破壊的変更になり得ます。

  • フィールドを削除する
  • パス名を変更する
  • レスポンス型を厳格化する
  • 必須フィールドを追加する
  • enum の値を削除する
  • ステータスコードを変更する

たとえば、次の差分は enum への値の追加なので、通常は後方互換です。

 parameters:
   - name: status
     in: query
     schema:
       type: string
-      enum: [draft, open, paid, void]
+      enum: [draft, open, paid, void, uncollectible]
Enter fullscreen mode Exit fullscreen mode

一方、void を削除すると、その値を使っているクライアントを壊す可能性があります。

命名が一貫しているか

既存APIがコレクションに複数形名詞を使っているなら、新しいAPIも合わせます。

/users
/users/{userId}/invoices
Enter fullscreen mode Exit fullscreen mode

エラー形式も統一します。

{
  "code": "USER_NOT_FOUND",
  "message": "ユーザーが見つかりません"
}
Enter fullscreen mode Exit fullscreen mode

新しいエンドポイントだけ別の形式を返すと、クライアント実装が複雑になります。

差分が読みやすいか

YAMLは差分が大きくなりがちです。次のルールを決めておくと、レビューしやすくなります。

  • キーの順序を固定する
  • フォーマッターを使う
  • パスを一定の順序で並べる
  • 意味のない並び替えをPRに含めない
  • 大きなリファクタリングと機能追加を同じPRに入れない

レビュー担当者には、アプリケーションコードと同じように仕様ファイルへインラインコメントしてもらいます。議論が該当行に紐づき、マージ後も履歴として残ります。

設計から開発へ

契約が main に入ったら、それをダウンストリーム成果物のソースにします。

GitネイティブAPIデザインの生成プロセス

1. コードを生成する

openapi-generator のようなツールを使うと、コミット済みのOpenAPIファイルからサーバースタブや型付きクライアントを生成できます。

例:

openapi-generator-cli generate \
  -i api/openapi.yaml \
  -g typescript-fetch \
  -o generated/client
Enter fullscreen mode Exit fullscreen mode

バックエンドでは、生成された型やスタブにビジネスロジックを実装します。リクエストとレスポンスの形状は、仕様に合わせて生成されます。

2. モックを起動する

モックサーバーは仕様を読み込み、エンドポイントごとのサンプルレスポンスを返します。これにより、バックエンド実装前でもフロントエンド開発を開始できます。

npx prism mock api/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

3. 契約テストを実行する

契約テストでは、実行中のAPIが仕様に一致しているかを検証します。

チェックする内容の例:

  • ステータスコード
  • レスポンスヘッダー
  • JSONスキーマ
  • 必須フィールド
  • enum 値
  • エラーレスポンス形式

仕様と実装が乖離した場合、CIを失敗させます。

4. ドキュメントを生成する

APIリファレンスはOpenAPIファイルから生成します。契約が変われば、ドキュメントも同じコミットで変わります。

手書きのドキュメントを別管理すると、更新漏れが発生します。Gitネイティブな運用では、ドキュメントも仕様から派生させます。

チームの成長に対応する規約

GitネイティブAPI設計をチームで続けるには、早い段階で規約を決めます。

1. 単一ファイルか分割ファイルかを決める

小規模APIなら、単一の openapi.yaml で十分です。

api/
  openapi.yaml
Enter fullscreen mode Exit fullscreen mode

エンドポイントが増えてきたら、$ref で分割します。

api/
  openapi.yaml
  paths/
    users.yaml
    invoices.yaml
  schemas/
    user.yaml
    invoice.yaml
Enter fullscreen mode Exit fullscreen mode

ビルド時に1つの仕様へバンドルします。

npx @redocly/cli bundle api/openapi.yaml -o dist/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

2. バージョン管理を明示する

OpenAPIの info.version を更新し、セマンティックバージョニングに従います。

openapi: 3.1.0
info:
  title: Billing API
  version: 1.4.0
Enter fullscreen mode Exit fullscreen mode

目安は次の通りです。

  • パッチ: 説明文の修正、仕様上の誤記修正
  • マイナー: 後方互換なエンドポイントやフィールドの追加
  • メジャー: 破壊的変更

破壊的変更では、必要に応じて /v2/ のような新しいパスプレフィックスを使います。

3. CHANGELOG.md を置く

Git履歴は正確ですが、コンシューマが読むには細かすぎます。仕様の隣に変更履歴を置きます。

# API Changelog

## 1.4.0
- `GET /users/{userId}/invoices` を追加
- `Invoice.status``uncollectible` を追加

## 1.3.1
- `Invoice.currency` の説明を修正
Enter fullscreen mode Exit fullscreen mode

4. CODEOWNERS で仕様を保護する

API契約の変更には、API管理者のレビューを必須にします。

# .github/CODEOWNERS
/api/openapi.yaml @api-stewards
/api/paths/ @api-stewards
/api/schemas/ @api-stewards
Enter fullscreen mode Exit fullscreen mode

これにより、善意の変更でも一貫性のない設計がマージされるのを防げます。

5. CIでリンティングする

仕様のスタイルや一貫性は、人間のレビュー前にCIで検出します。

# .github/workflows/api-lint.yml
name: API Lint

on:
  pull_request:
    paths:
      - "api/**"

jobs:
  spectral:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Spectral
        run: npx @stoplight/spectral-cli lint api/openapi.yaml --fail-severity warn
Enter fullscreen mode Exit fullscreen mode

CIリンティングと CODEOWNERS を組み合わせると、すべての契約変更に対して自動チェックと人間のレビューを強制できます。

よくある落とし穴と回避策

仕様とコードが乖離する

最も危険なのは、仕様ではある形を定義しているのに、実行中のAPIが別の形を返すことです。

回避策は、CIで契約テストを実行することです。

PR作成
  -> API lint
  -> サーバー起動
  -> 契約テスト
  -> 仕様とレスポンスを検証
  -> 不一致なら失敗
Enter fullscreen mode Exit fullscreen mode

乖離を本番障害ではなく、パイプラインの失敗として検出します。

PRが大きすぎる

20個のエンドポイントを1つのPRに入れると、レビューは形だけになります。

回避策:

  • 1 PR = 1 エンドポイント
  • 1 PR = 1 変更目的
  • リファクタリングと機能追加を分ける
  • 破壊的変更は専用PRにする

小さい差分ほど、実際にレビューされます。

手書き成果物が増える

クライアント、スタブ、ドキュメントを手書きすると、仕様とズレます。

回避策:

  • クライアントは仕様から生成する
  • サーバースタブも仕様から生成する
  • ドキュメントも仕様から生成する
  • 生成手順をCIまたはビルドスクリプトに含める

手書きのAPI成果物は、乖離の兆候として扱います。

YAMLのマージ競合が増える

長期間のブランチで同じ openapi.yaml を編集すると、競合が起きやすくなります。

回避策:

  • 短命ブランチを使う
  • 小さなPRにする
  • キー順序を固定する
  • ファイルをリソース単位に分割する
  • 意味のない整形変更を避ける

トランクベース開発と小さなPRを組み合わせると、競合の多くは発生前に防げます。

Apidogの役割

GitネイティブなAPIワークフローは、テキストエディタとCLIだけでも実行できます。一方で、多くのチームはGitを信頼できる情報源にしたまま、GUIで設計したいと考えます。

ApidogのSpec-Firstモードは、そのための選択肢です。OpenAPIファイルをGitリポジトリに保持しながら、ビジュアルデザイナーやエディタで契約を編集できます。編集内容はリポジトリ内のファイルと同期されるため、ブランチ、PR、履歴、レビューの流れを維持できます。

セットアップの詳細は、Spec-Firstモードのドキュメントを参照してください。

重要なのは、ツールそのものではありません。リポジトリを唯一の信頼できる情報源にし、GUIはそのビューとして使うことです。

FAQ

GitネイティブAPIデザインはOpenAPI専用ですか?

いいえ。テキストベースの契約フォーマットであれば同じ考え方を適用できます。

例:

  • OpenAPI
  • AsyncAPI
  • gRPC の .proto
  • GraphQL SDL

契約がテキストファイルで、差分、ブランチ、レビューが可能であれば、Gitネイティブに扱えます。

Gitネイティブワークフローで破壊的変更をどう扱いますか?

破壊的変更は、明示的に扱います。

実践例:

  • break/api- ブランチを使う
  • メジャーバージョンを上げる
  • CODEOWNERS で管理者承認を必須にする
  • 可能なら新旧形式を並行提供する
  • 古いパスやフィールドには非推奨期間を設ける
  • CHANGELOG.md に影響範囲を書く

PRの差分、バージョン番号、変更履歴を組み合わせて、コンシューマに変更を伝えます。

API仕様はコードと同じリポジトリに置くべきですか?

通常、同じチームが仕様と実装を所有しているなら、同じリポジトリに置くのが簡単です。

メリット:

  • 契約と実装を同じPRで変更できる
  • CIで契約テストを実行しやすい
  • バージョンの対応関係が明確になる

一方、多数のチームが同じAPI仕様を共有し、独立したリリース管理が必要な場合は、仕様専用リポジトリを検討します。

仕様とコードが乖離するのを防ぐにはどうすればよいですか?

CIで契約テストを実行します。実行中のサーバーにリクエストを送り、コミット済み仕様に対してレスポンスを検証します。

さらに、次の運用を組み合わせます。

  • スタブを仕様から生成する
  • クライアントを仕様から生成する
  • ドキュメントを仕様から生成する
  • 仕様変更PRにレビューを必須にする
  • lintと契約テストをPRごとに実行する

乖離を本番バグではなく、CIの失敗として検出するのがポイントです。

結論

GitネイティブAPIデザインは、製品ではなく開発規律です。API契約をソースコードとして扱い、ブランチで変更し、PRでレビューし、コミット済み仕様からモック、テスト、クライアント、ドキュメントを生成します。

小さく始めるなら、次の順序がおすすめです。

  1. 仕様をリポジトリに置く
  2. API変更をPRレビュー必須にする
  3. CODEOWNERS を設定する
  4. CIで仕様リンティングを実行する
  5. モックとドキュメントを仕様から生成する
  6. 契約テストをCIに追加する

このワークフローを続けると、Git履歴がAPI履歴になります。誰が、いつ、なぜ契約を変更したのかを追跡でき、設計レビューも実装前に行えます。

Gitに仕様を保持しながらビジュアルに設計したい場合は、ApidogのSpec-Firstモードを試し、双方向同期がこのワークフローにどう組み込めるか確認してください。

Top comments (0)