MENU

Web APIの設計 まとめ

この本は、単に技術的な実装方法を解説するのではなく、「ユーザーにとって価値のあるAPIをどう設計するか」というプロセスとマインドセットに重きを置いています。エンジニアが陥りがちな「実装都合のAPI」から脱却し、「使いやすいAPI」を作るための設計論です。


第1部 APIデザインの基礎

目次

第1章 API設計の重要性

多くのプロジェクトでは、「APIが必要だ」となった瞬間、すぐにコードを書き始めてしまいます。しかし、著者は「コードを書く前に設計せよ」と強く警告します。なぜなら、APIは一度公開されると、それは利用者(コンシューマ)との「契約」となり、容易に変更できなくなるからです。

1. 良いAPIと悪いAPIの違い

APIの価値は、「利用者がどれだけ簡単に目的を達成できるか」で決まります。

特徴悪い設計のAPI (実装主導)良い設計のAPI (デザイン主導)
視点サーバー内部のデータ構造やDBスキーマをそのまま露出する。利用者が何をしたいか(ユースケース)に基づいて設計される。
学習コスト内部ロジックを理解しないと使えない。ドキュメントが難解。直感的で、ドキュメントを見なくてもある程度推測できる。
影響アプリ側のコードが複雑になり、バグを生みやすい。アプリ開発が加速し、ビジネスの価値提供が早まる。

2. APIデザインファースト (API Design First)

著者が提唱する最も重要な原則です。

APIデザインファーストの原則

実装に着手する前に、インターフェース(API仕様)を完全に定義し、ステークホルダーと合意するプロセス。

  • メリット:
    • 実装の手戻りを防ぐ。
    • フロントエンドとバックエンドの並行開発が可能になる。
    • ユーザー視点が欠落するのを防ぐ。

第2章 APIの目的とユーザーの特定

優れた設計を行うためには、技術的な詳細(JSONの形式やHTTPメソッド)を決める前に、「誰が、何のために使うのか」を明確にする必要があります。

1. APIゴールキャンバス (API Goals Canvas)

著者は、APIの目的を整理するためのフレームワークとして「APIゴールキャンバス」のようなアプローチを推奨しています。以下の要素を特定します。

  1. ユーザー(Users): 誰が使うのか?(モバイルアプリ開発者、パートナー企業、社内システムなど)
  2. ニーズ(Needs): 彼らは何を解決したいのか?
  3. 機能(Capabilities): そのためにAPIは何を提供すべきか?

2. ユーザー視点の獲得

エンジニアは「データベースにユーザーテーブルがあるから、GET /users を作ろう」と考えがちですが、これは誤りです。

  • 誤ったアプローチ: 内部データモデルをそのままAPIにする。
  • 正しいアプローチ: ユーザーの行動(「商品を検索する」「カートに追加する」)からAPIを導き出す。
graph TD
    A[ビジネス要件] --> B{ユーザーの目的は?}
    B -->|商品を探したい| C[商品検索API]
    B -->|購入したい| D[注文作成API]
    C --> E[必要なデータ設計]
    D --> E
    
    style E fill:#f9f,stroke:#333,stroke-width:2px,stroke-dasharray: 5 5

実装の詳細(DB設計など)は、API設計のに来るべきものです。


第3章 REST APIの基本設計

ユーザーの目的が定まったら、それを具体的なWeb APIのインターフェース(RESTful API)に落とし込んでいきます。ここでは「リソース」と「アクション」の識別が鍵となります。

1. リソースの識別 (Identifying Resources)

ユーザーのやりたいことを「名詞(リソース)」として表現します。

  • 概念の抽出:
    • 「本を借りたい」 → リソースは BookLoan
    • 「お金を送金したい」 → リソースは TransferAccount

2. アクションの定義 (Mapping Actions)

リソースに対する操作をHTTPメソッドにマッピングします。

操作 (ユーザーの意図)HTTPメソッドURIの例備考
一覧取得GET/booksフィルタリングパラメータを活用する
詳細取得GET/books/{id}一意な識別子を使用する
新規作成POST/books成功時は 201 Created を返す
更新 (置換)PUT/books/{id}リソース全体を置き換える
更新 (一部)PATCH/books/{id}変更箇所のみ送信する
削除DELETE/books/{id}物理削除か論理削除かは実装の問題

3. URL設計のベストプラクティス

  • 階層構造: 親子関係がある場合は /authors/{id}/books のように階層化する。
  • シンプルさ: /system/v1/data/getBooks のようなRPCスタイル(動詞を含むURL)は避け、/books とシンプルにする。

第4章 APIの記述とOpenAPI (Swagger)

設計したAPIをどう表現し、共有するか。ここで登場するのが API記述言語(API Description Language) です。本書では、業界標準である OpenAPI Specification (OAS) の使用を強く推奨しています。

1. なぜ仕様書をコードより先に書くのか

コードからドキュメントを生成するのではなく、仕様書(OASファイル)を先に書き、それを正(Source of Truth)とする手法です。

API記述言語を使うメリット

  1. 人間と機械の両方が読める: ドキュメント生成だけでなく、コード生成やテスト自動化に使える。
  2. モックサーバーの構築: 実装が1行もなくても、OASがあればモック(偽のAPI)を立ててフロントエンド開発を始められる。
  3. コミュニケーション: ExcelやWikiでの仕様管理による「実装との乖離」を防ぐ。

2. OpenAPIの基本構成

エンジニアはYAML形式で以下のように設計図を描きます。

openapi: 3.0.0
info:
  title: Book Store API
  version: 1.0.0
paths:
  /books:
    get:
      summary: 書籍一覧の取得
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Book'
components:
  schemas:
    Book:
      type: object
      properties:
        id:
          type: string
        title:
          type: string

3. 設計の可視化

OASを書くことで、Swagger UIなどのツールを使って設計を「見える化」できます。これにより、非エンジニアや他のチームメンバーと「この設計で使いやすいか?」を実装前に議論することが可能になります。

第2部 ユーザーブルなAPIの設計

第5章 直感的なAPIを設計する (Designing Straightforward APIs)

この章のテーマは、「ユーザーに考えさせない(Don’t make me think)」です。

優れたAPIは、リクエストやレスポンスを見ただけで使い方が想像できます。逆に、ドキュメントを隅から隅まで読まないと理解できないAPIは「直感的」ではありません。

1. 実装の詳細を漏らさない (Avoid Leaky Abstractions)

エンジニアは、DBのカラム名や内部用語をそのままAPIに出しがちですが、これはユーザーにとってノイズでしかありません。

  • 悪い例 (内部構造の露出):
{
  "C_ID_PK": 12345,       // DBの主キー名そのまま
  "flg_del": 0,           // 削除フラグ(内部ロジック)
  "rel_T_ORDER": [...]    // ORMのリレーション名
}
  • 良い例 (ユーザー視点):
{
  "id": "12345",
  "status": "active",
  "orders": [...]
}

2. 直感的なデータ表現

データの構造やプロパティ名は、ユーザーのメンタルモデル(常識)に合わせるべきです。

観点悪い設計良い設計理由
単位"duration": 150"duration": "2h 30m"
または "durationMinutes": 150
単位が不明だとバグの原因になる (ミリ秒? 秒? 分?)
ブール値"valid": "yes"
"deleted": 1
"isValid": true
"isDeleted": true
JSONの true/false 型を使い、名前は質問形(is, has)にする
列挙型"status": 1"status": "pending"マジックナンバー(1=保留)は解読が必要。文字列で意味を伝える
構造無意味に深いネスト
data.info.detail.value
フラットな構造
value
必要な情報に最短でアクセスさせる

3. エラー表現のわかりやすさ

エラーは「何が起きたか」だけでなく「どうすれば直るか」を伝えるべきです。

重要なルール: エラーメッセージは、APIの開発者(あなた)ではなく、APIの利用者(ユーザー)に向けて書く。


第6章 予測可能なAPIを設計する (Designing Predictable APIs)

第6章のキーワードは「一貫性(Consistency)」です。

ユーザーは、一つのエンドポイントの使い方を覚えたら、他のエンドポイントも「たぶん同じだろう」と予測して使います。その期待を裏切らない設計が「予測可能なAPI」です。

1. 一貫性のある4つのレベル

API全体で統一すべき要素は以下の4つです。

mindmap
  root((一貫性))
    URL構造
      パスのパターン
      単数/複数の統一
    データ表現
      日付フォーマット
      IDの型 (数値or文字列)
      プロパティ命名規則
    パラメータ
      ページネーション
      フィルタリング
      ソート方法
    フロー
      エラーの形式
      認証手順
      成功時のレスポンス

2. 具体的な統一基準

現場でよく揉めるポイントに対し、著者は明確な基準を持つことを推奨しています。

項目統一すべきポイント具体例
IDの表現すべて文字列か、すべて数値か全て文字列("id": "123")で統一推奨(JSの数値精度問題回避のため)
日付形式フォーマットの統一ISO 8601 (YYYY-MM-DDThh:mm:ssZ) 一択
ページネーションパラメータ名と挙動常に pagesize を使う(offset/limit と混在させない)
部分更新HTTPメソッドPUT(全置換)と PATCH(部分更新)を明確に使い分ける

「驚き最小の原則」

API利用者が「えっ、こっちは created_at なのに、あっちは creationDate なの?」と驚くような設計は排除しましょう。


第7章 安全なAPIを設計する (Designing Secure APIs)

セキュリティは、APIが完成してから「後付け」するものではなく、「設計(デザイン)の一部」です。使いやすさとセキュリティはトレードオフになりがちですが、バランスを取る方法が解説されています。

1. セキュリティの分割統治

「誰が(Authentication)」「何をできるか(Authorization)」を明確に分けます。

  • 認証 (Authentication): ユーザーが誰であるかを確認する(パスポート)。
  • 認可 (Authorization): そのユーザーに何の権限があるかを確認する(チケット)。

2. センシティブデータの設計

API設計者は、データの中に「見せてはいけないもの」が含まれていないか常に監視する必要があります。

  • GDPR/個人情報: user.passwordcredit_card.cvv がレスポンスに含まれないよう、データモデル(DTO)をAPI専用に定義する。
  • 詳細すぎるエラー: Database connection failed at 192.168.1.5 のようなエラーは、攻撃者に内部ネットワーク構造を教えているようなものです。

3. スコープによる権限管理 (OAuth 2.0 Scopes)

OAuth 2.0のスコープを使用して、APIの機能ごとに細かく権限を設計します。

graph LR
    User[ユーザー]
    App[サードパーティアプリ]
    AuthServer[認証サーバー]
    ResourceServer[APIサーバー]

    User -- "(1) 権限委譲 read:profile" --> AuthServer
    AuthServer -- "(2) アクセストークン発行 scope: read:profile" --> App
    App -- "(3) トークン提示 GET /profile" --> ResourceServer
    
    subgraph API内部のチェック
    ResourceServer -- "スコープは read:profile か?" --> Check{OK?}
    Check -- Yes --> Response[データ返却]
    Check -- No --> Error[403 Forbidden]
    end

4. 設計によるセキュリティ対策

  • 機密情報はURLに入れない: クエリパラメータやパスにAPIキーやトークンを含めない(ログに残るため)。ヘッダーを使用する。
  • リソース列挙攻撃の防止: /users/1, /users/2 と順番にアクセスされないよう、推測不可能なID(UUIDなど)の使用を検討する。

第3部 コンテキストに応じたAPIデザイン

第8章 整理されたAPIを設計する (Designing Organized APIs)

APIの機能が増え、エンドポイントが数十、数百と増えてくると、設計の一貫性を保つことや、利用者が目的の機能を見つけることが困難になります。この章では、「APIの分割統治」について解説します。

1. APIの構造化とグルーピング

巨大なAPI定義(OpenAPIファイルなど)をそのまま公開しても、利用者は圧倒されてしまいます。ディレクトリ構造のように整理する必要があります。

  • タグ付け (Tagging): 機能やリソースごとにグループ化します(例: Users, Products, Orders)。
  • 名前空間 (Namespacing): URIパスを使って視覚的に分類します。
    • /sales/orders
    • /support/tickets
    • /admin/users

2. コンテキスト境界の識別

すべての機能を1つの「モノリシックAPI」に詰め込むべきではありません。ドメイン駆動設計(DDD)の考え方を取り入れ、「誰のための機能か」によってAPIを分割することも検討します。

分割アプローチ特徴適したケース
機能別分割全機能を1つのAPIサーバで提供し、パスで分ける。小〜中規模のシステム。開発チームが少人数の場合。
BFF (Backend For Frontend)モバイル用、Web用、管理画面用など、クライアントごとに専用APIを作る。UIごとの要求が大きく異なる場合。
マイクロサービスドメイン(注文、在庫、配送)ごとにAPIを物理的に分ける。大規模組織。チームごとに独立してデプロイしたい場合。

重要な視点:

APIを分割しても、利用者にとって「使い勝手(ユーザー体験)」が分断されないように注意が必要です。認証方法やエラールールの統一は維持しなければなりません。


第9章 進化するAPIを設計する (Designing Evolving APIs)

第9章は、すべてのAPI開発者が直面する最大の難問、「バージョニング(Versioning)」と「後方互換性(Backward Compatibility)」についてです。

1. 破壊的変更 vs 非破壊的変更

APIを進化させる際、既存の利用者を壊さないことが最優先です。

  • 非破壊的変更 (Safe): クライアントの修正が不要な変更。
    • 新しいエンドポイントの追加。
    • レスポンスJSONへの新しいフィールドの追加(クライアントが未知のフィールドを無視する実装になっている前提)。
    • 必須ではない(Optionalな)リクエストパラメータの追加。
  • 破壊的変更 (Breaking): クライアントが動かなくなる変更。
    • フィールド名の変更や削除。
    • データ型の変更(数値 → 文字列)。
    • 必須パラメータの追加。

2. バージョニング戦略

破壊的変更が避けられない場合、新しいバージョンを作る必要があります。

戦略URIの例メリットデメリット著者の評価
URIバージョニング/v1/usersわかりやすい。キャッシュ制御が容易。リソースの永続的なIDが変わってしまう(論理的な欠点)。最も現実的で推奨
ヘッダーバージョニングX-Api-Version: 1URIが綺麗に保たれる。ブラウザで確認しづらい。キャッシュ設定が複雑になる。許容範囲
メディアタイプAccept: application/vnd.myapi.v1+json最もRESTful。実装とテストが面倒。利用者のハードルが高い。複雑すぎる場合が多い

3. セマンティックバージョニングの適用

APIのバージョン番号(MAJOR.MINOR.PATCH)に意味を持たせます。

  • MAJOR: 破壊的変更を含む(v1 → v2)。利用者はコード修正が必要。
  • MINOR: 新機能追加(v1.1)。後方互換性あり。
  • PATCH: バグ修正(v1.1.1)。後方互換性あり。

究極の目標:

「バージョンアップをしない(v1のまま進化し続ける)」ことが最高のDX(開発者体験)です。可能な限り破壊的変更を避け、拡張(追加)だけで進化させる設計を目指しましょう。


第10章 ネットワーク効率の良いAPIを設計する (Designing Network-Efficient APIs)

モバイル回線や低速なネットワーク環境では、APIの「通信回数」と「データ量」がボトルネックになります。第10章では、パフォーマンスを最適化する設計パターンを学びます。

1. N+1問題と「おしゃべりなAPI (Chatty API)」

REST APIの原則に忠実になりすぎると、必要な情報を集めるために何度もリクエストが必要になる問題が発生します。

  • 問題: ユーザー一覧を取得し、それぞれの詳細情報を個別に取得する。
    1. GET /users (IDリスト取得)
    2. GET /users/1
    3. GET /users/2
    • 通信回数が増え、遅延(レイテンシ)が積み重なる。

2. データ結合(Expansion / Embedding)

関連するリソースを一度のリクエストで取得できるようにします。

  • 解決策: クエリパラメータで埋め込みを指定する。
    • GET /users/1?embed=orders
    • レスポンスにはユーザー情報だけでなく、そのユーザーの注文履歴も含まれる。
graph LR
    subgraph Chatty_API [おしゃべりなAPI: 往復が多い]
    C1[クライアント] -- "Step1: GET /users/1" --> S1[サーバー]
    S1 -- "Step2: User Data" --> C1
    C1 -- "Step3: GET /orders?uid=1" --> S1
    S1 -- "Step4: Orders Data" --> C1
    end

    subgraph Efficient_API [効率的なAPI: 1回で済む]
    C2[クライアント] -- "Step1: GET /users/1?embed=orders" --> S2[サーバー]
    S2 -- "Step2: User + Orders Data" --> C2
    end
    
    style Chatty_API fill:#fff5f5,stroke:#f99,stroke-width:2px
    style Efficient_API fill:#f0fff4,stroke:#9f9,stroke-width:2px

3. 部分レスポンス(Filtering / Projection)

逆に、「データ量が多すぎる」問題を解決します。モバイルアプリでは、巨大なJSONのパースコストも無視できません。

  • 解決策: 必要なフィールドを指定する。
    • GET /users/1?fields=id,name
    • addresshistory などの不要な巨大データを除外し、idname だけを返す。
  • GraphQLとの比較:
    • この章で紹介されるテクニック(Expansion/Filtering)は、GraphQLが解決しようとしている課題と同じです。RESTでこれらを取り入れることで、GraphQLを導入せずとも十分なパフォーマンスを得られる場合があります。

💡GraphQLとの比較の部分めちゃくちゃ勉強になった

4. バルク操作(Bulk Operations)

複数のリソースを一度に作成・更新・削除する仕組みです。

  • POST /users/batch で複数のユーザーJSONを配列で送信する。
  • これにより、ネットワークのラウンドトリップ回数を劇的に削減できます。

第11章 ユーザーのためのAPIドキュメント (Designing Documentation)

「コードはドキュメントよりも雄弁である」という言葉がありますが、APIにおいてそれは通用しません。APIのソースコードを見ることのできない利用者にとって、「ドキュメントこそがAPIそのもの(製品)」です。

1. ドキュメントの構成要素

OpenAPI (Swagger) から自動生成されるリファレンスだけでは不十分です。著者はドキュメントを以下の要素に分類しています。

種類目的内容の例対象読者
リファレンス辞書的な詳細確認パラメータの型、必須/任意、エラーコード一覧実装中の開発者
ガイド / チュートリアル目的達成の手順「最初の5分でHello World」「認証の通し方」「典型的なユースケース」初めて使う人
概念説明 (Topics)背景知識の理解ページネーションの仕組み、レートリミットのポリシーアーキテクト、開発者

2. 「3ペイン」レイアウトの推奨

優れたAPIドキュメント(Stripeなど)は、共通して「3カラム構成」を採用しています。

  1. 左カラム (ナビゲーション): 目次、検索。迷子にさせない。
  2. 中央カラム (説明): 人間向けの解説テキスト。
  3. 右カラム (コード): すぐにコピペできるコードスニペット(cURL, Python, Node.jsなど)。

3. TTFHW (Time To First Hello World)

ドキュメントの品質を測る指標として、「ユーザーがドキュメントを開いてから、最初のリクエストを成功させるまでの時間」を最小化すべきです。

  • Try it outボタン: ドキュメント上で直接APIを叩ける機能(Swagger UIなど)は必須です。

第12章 APIの成長戦略とガバナンス (Growing APIs)

APIが1つや2つなら個人のスキルで管理できますが、企業内で数十、数百のAPIが乱立し始めると、品質のバラつきが問題になります。ここでは「APIガバナンス」の重要性が語られます。

1. ガバナンスの役割:警察官ではなく教師であれ

多くの組織が「API警察」を作ろうとしますが、それは失敗します。

  • API警察 (Police): 「ルール違反だ、やり直し!」と罰を与える存在。開発のボトルネックになり、チームから嫌われる。
  • API教師 (Teacher): 「こうすればもっと良くなるよ」とガイドし、ツールを提供する存在。

ゴール: 「正しいことをする(ガイドライン準拠)」のを、「間違ったことをする」よりも簡単にすること。

2. APIスタイルガイドの策定

チーム全員が従うべき「設計の憲法」を作ります。

  • URLの命名規則(ケバブケースかキャメルケースか)
  • 日付フォーマットの統一
  • エラーオブジェクトの共通スキーマ

3. 自動化されたレビュー (API Linting)

スタイルガイドを目視でチェックするのは非効率です。Spectral などのリンター(静的解析ツール)を導入し、OpenAPIファイルを自動チェックします。

graph LR
    Dev[開発者]
    Repo[リポジトリ]
    CI[CIパイプライン]
    Reviewer[人間レビュー]

    Dev -- "(1) 設計 OAS 作成" --> Repo
    Repo -- "(2) Commit" --> CI
    
    subgraph Automation
    CI -- "(3) API Lint (Spectral)" --> Result{OK?}
    end
    
    Result -- "No (構文エラー/規約違反)" --> Dev
    Result -- "Yes" --> Reviewer
    
    Reviewer -- "(4) 設計の妥当性確認" --> Approve[承認/マージ]
    
    style Automation fill:#e6fffa,stroke:#38b2ac,stroke-width:2px
  • 機械ができること: 命名規則チェック、descriptionの有無チェック。
  • 人間がやるべきこと: 「このAPIはユーザーの課題を解決しているか?」「使いやすいか?」の判断。

第13章 Web APIの設計 (The Design of Web APIs)

最終章は、本書全体の哲学のまとめです。技術書でありながら、著者は「共感(Empathy)」という言葉で締めくくっています。

1. コンテキストこそが王様 (Context is King)

「RESTが絶対だ」「GraphQLが最強だ」という技術論争には意味がありません。

  • 誰が使うのか?(モバイルアプリ? サーバー間通信?)
  • どんな制約があるのか?(低速回線? 高セキュリティ?)
  • 正解は常にコンテキストの中にある。

2. デザインは終わらない

APIをリリースした日はゴールではなく、スタートです。

  • 利用者のフィードバックを聞く。
  • エラーログを監視して、ユーザーがつまずいている箇所を見つける。
  • ドキュメントを更新し続ける。

結論:

優れたAPI設計者とは、JSONの書き方を熟知している人ではなく、「画面の向こうにいる開発者の痛みを想像し、取り除くことができる人」のことです。


最終アクションプラン:明日から実践できるAPIガバナンス

全13章の学びを統合し、組織レベルでAPI品質を向上させるためのステップです。

  1. [自動化] APIリンター (Spectral) を導入する
    • これが最も費用対効果が高いアクションです。「URLは小文字であるべき」「説明文は必須」といったルールを定義した .spectral.yaml を配置し、VS Code等のエディタでリアルタイムに警告が出るようにしてください。
    • 効果: レビューでの「つまらない指摘(てにをは、命名規則)」がゼロになり、本質的な議論に集中できます。
  2. [ドキュメント] 「Getting Started」を書く
    • 自動生成されたAPIリファレンスの冒頭に、手書きの「3ステップで使い始めるガイド」を追加してください。
      1. 認証キーの取得方法
      2. 基本的なリクエストの投げ方
      3. 最初のレスポンスの見方
    • これがあるだけで、APIの定着率は劇的に上がります。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次