Upgrade to Pro — share decks privately, control downloads, hide ads and more …

現場で役立つAPIデザイン

草薙昭彦
February 14, 2025

 現場で役立つAPIデザイン

Web APIは外部連携のために公開するだけでなく、システム内部での利用も一般的になっており、重要性はますます高まっています。しかし、APIデザインについての知見はまだ広く浸透していません。書籍やオンライン情報はいろいろありますが、本セッションではその中から重要な要素をピックアップし、実際の著名なサービスに適用されている例も取り上げながら解説します。すぐに開発現場で役立ちます!Developers Summit 2025での発表資料です。

草薙昭彦

February 14, 2025
Tweet

More Decks by 草薙昭彦

Other Decks in Technology

Transcript

  1. All rights reserved by Postman Inc 現場で役立つ API デザイン 草薙

    昭彦 テクノロジーエバンジェリスト #devsumi
  2. はじめに • 対象:Web API を使ったことはあるけど設計に初めて取り組む方 • REST API の話をします •

    基本的に、ここ 20年くらい API デザインの原則は大きくは変わっていませんが、な るべく最近の事情に沿った話をします • 詳細なデザインパターンは他にもたくさん ありますので、あとは書籍などで @postman_japan
  3. なぜ API デザイン = API 仕様が重要なのか • API 仕様書作ってますか? どのフェーズで作ってますか?

    • よくあるフロー ◦ 実装しながら API を整備、最後にアノテーションなどから API spec を出力、 補足を文書や Wiki などに記述 • 残念ながら、負債になることが多い・・ • どうする?→ API ファースト 開発 ◦ 関係者間で共同で API 仕様を定め、常に 最新の変更を反映し、仕様を元にテスト、 実装、ドキュメントを開発する @postman_japan
  4. API デザインのアプローチ @postman_japan インサイドアウト アウトサイドイン アジャイル 既存のバックエンドシステム が出発点 。バックエンドの内部 実装の詳細と機能が、

    API を 通して公開される。 きめ細かな制御、内部プロセス への直接アクセス、豊富な機 能を提供するが、API が密結 合になり、利用者の複雑さが増 す可能性がある。 API 利用者のニーズと要件に 基づいて API を設計すること に重点を置き、内部の複雑さを 抽象化する。シンプルさ、使い やすさ、柔軟性を優先し、利用 者が基礎となる実装を知らなく ても API と対話できるようにす る。 保守と進化が容易な疎結合の API を生み出すことが多い。 開発者は完成した仕様書なし に API の作業を開始する。開 発プロセス全体を通して、柔軟 性、コラボレーション、変化へ の対応力が重視される。開発 者は、進化する要件や優先事 項に適応しながら迅速に反復 しなければならない。 開発者、利害関係者、エンド ユーザー間の緊密なコラボ レーションを奨励 する。
  5. API で実現する 意図を決定する 仕様書により API コントラクトを定義 する モックとテストによ り仮説を 検証する

    API を 文書化する API ファーストでは @postman_japan https://www.postman.com/api-platform/api-design/
  6. 良い API を目指す • HTTP 標準、Restful の原則に従おう ◦ 良い API

    の設計には HTTP 標準、Restful の原則の理解が必要 ◦ 標準を使用することで、理解がしやすい、バグの混入を防ぐ、パフォーマンス の最適化、再利用しやすくなるなどのメリットを得られる • 同時に、ポピュラーな API で使われている「現実解」にも目を向けよう ◦ 原則だけではうまくいかないケースがある ◦ 現実の API には深い検討や試行錯誤を経て落とし込まれたものがある ◦ API のユーザー(開発者)は、よく見る API のスタイルに慣れている @postman_japan
  7. RESTful の原則 • 統一インターフェースの使用 コンポーネントの動作を定めるための複数のアーキテクチャ制約と、単一の URL で識別できる一意のリソース • クライアントとサーバーの分離 それぞれの関心事を分離することで、独立して開発して柔軟に機能強化することができる

    • ステートレスな操作 リクエストには必要な情報をすべて含むようにし、サーバーはクライアントの状態に関する情報を保持しない • キャッシュ可能なレスポンス レスポンス内のデータは、キャッシュ可能か不可能かラベル付けされている必要がある • レイヤー化されたシステムアーキテクチャ 階層的なレイヤーで構成されるアーキテクチャで実現され、異なるレイヤーの中は見えないようになっている • コード・オン・デマンド サーバーは必要に応じて実行可能コードを送信することもでき、クライアントの機能を拡張することができる @postman_japan
  8. Zalando RESTful API ガイドライン • ファッション EC を展開するヨーロッパ最大手 Zalando による、RESTful

    API の設計ガイ ドライン https://github.com/zalando/restful-api-guidelines • 日本語訳 by @kawasima さん https://restful-api-guidelines-ja.netlify.app/ • API を運用する方は、自分たちのサービス に合わせたガイドラインを整備するのがおす すめ @postman_japan
  9. 代表的なガイドライン • API エンドポイントには明確で一貫性のある名前を使う • 必須情報にはパスパラメーターを使い、追加情報にはクエリ文字列を使う • エンドポイントが何をするかに基づいて正しい HTTP メソッドを使用する

    • API がデータを正しく受け取り、応答できるように設計する • よく使うデータをキャッシュして API を高速化する • 目的にあった認証・認可方式を選定 • API の使い方を明確かつ詳細に説明するドキュメントを作る @postman_japan
  10. 適切な抽象化を • 実装に依存する構造を見せるのは不適切 ◦ 例: データベースのテーブルをそのまま API にマッピング • アプリの用途に合わせすぎるのも不適切

    ◦ 例: Web ページ毎に API を用意する ◦ ただし内部 API の場合は適切なケースがある • 複数の用途で共通化できるか、将来に渡り有効か、管理の手間は大きすぎない か、などを検討 @postman_japan
  11. 要点 • REST API は HTTP プロトコルのしくみを活用 ◦ 標準を使用することで、理解がしやすい、バグの混入を防ぐ、再利用しやすく なるなどのメリット

    • REST API を作る場合、CRUD (Create、Read、Update、Delete) 操作のために HTTP メソッドを正しい 方法で使うことが重要 @postman_japan
  12. よく使う HTTP メソッド @postman_japan メソッド CRUD 操作 リクエスト レスポンス GET

    読み込み 空 求める情報 POST 新規作成 新規データ ID 付きの新規データ PUT 更新・置き換え データ全体 更新済みデータ DELETE 削除 空 成功メッセージ PATCH 更新・置き換え データの一部 更新済みデータ HEAD 情報取得 空 ヘッダー OPTIONS 許可メソッド取得 空 許可メソッド
  13. リクエストデータ形式 • Content-Type ヘッダーは、リクエストボディのデータ形式を指定 • API ドキュメントに受け付けるデータ形式を明示することが重要 @postman_japan Content-Type の値

    データ形式 application/json JSON application/x-www-form-urlencoded フォームデータ multipart/form-data マルチパートフォームデータ application/octet-stream バイナリデータ
  14. レスポンスデータ形式とネゴシエーション • クライアントが受け付ける形式を Accept リクエストヘッダーで指定 ◦ q Quality Value) をつけることで優先度を明示することができる

    Accept: application/json, text/javascript, */*;q=0.01 • サーバーはクライアントの希望を考慮してデータ形式を決定し、Content-Type レスポンスヘッダーでレスポンスボディの形式を指定 • ただし、クエリパラメータで希望の形式を指定する方法もよく使われる ◦ 例:/products?format=json @postman_japan
  15. 適切なステータスコードを返す • HTTP 標準のステータスコードを利用 @postman_japan ステータ スコード 説明 100 番台

    情報 200 番台 成功 300 番台 リダイレクト 400 番台 クライアント起因のエラー 500 番台 サーバー起因のエラー 200 標準の成功レスポンス 207 レスポンスは複数のステータスを含む 304 リソースは未変更 400 一般的なエラー・未知のエラー 404 リソースのアクセス権限がない 415 リソースが存在しない 429 リクエスト数が超過 503 サーバは一時的に利用不可 主な例
  16. Postman ステータスコード福引 レアなステータスコードを出して豪華賞品をゲット! 418 Iʼm a Teapot (私はティーポット 🫖) 451

    Unavailable for Legal Reasons (法的な理由により利用不可 🚫) 218 This is Fine (これでいいのだ 🙆) 420 Enhance Your Calm (冷静さを高めよう 😎) 530 Site Frozen (サイト凍結中 🥶) 1等 103 Early Hints (早めのヒント 💡) 300 Multiple Choices (複数選択 ✅) 410 Gone (なくなった 👋) 422 Unprocessable Entity (処理不可の項目 🙅) 426 Upgrade Required (要アップグレード ⤴) 2等 ステータスコード 1xx (大丈夫? 🤨) 3等 ステータスコード 3xx (他を当たれ ➡) ステータスコード 4xx (お前が悪い 🫵) ステータスコード 5xx (サーバーが悪い 💢) 5等 ステータスコード 2xx (いい調子 😚) 4 等 6等 6等
  17. エラーレスポンス • 標準的な HTTP ステータスコードを使用する • レスポンスボディにも明確なエラーメッセージとエラーの詳細を含める ◦ 詳細な情報を返すことで API

    利用者がすべき振る舞いが明確になる ◦ RFC7807 Problem Details for HTTP APIs の利用 • API のどこでも同じ エラー形式を使用する @postman_japan HTTP/1.1 403 Forbidden Content-Type: application/problem+json Content-Language: en { "type": "https://example.com/probs/out-of-credit", "title": "You do not have enough credit.", "detail": "Your current balance is 30, but that costs 50.", "instance": "/account/12345/msgs/abc", "balance": 30, "accounts": ["/account/12345", "/account/67890"] }
  18. API のバージョン管理 • API を変更しても従来からのユーザーが API を使用し続けられることが重要 • セマンティックバージョニング (major.minor.patch)

    ◦ メジャーバージョン: 後方互換性のない変更 → 新・旧 API を併存させる ◦ マイナーバージョン・パッチバージョン: 後方互換性のある変更 @postman_japan 指定方法 例 説明 URL バージョニング /v1/products URL にメジャーバージョンを含める クエリパラメータ /products?price=desc クエリとしてバージョンを指定 ヘッダー Accept: application/ vnd.api+json;version=1 コンテンツネゴシエーションを使用
  19. キャッシングはヘッダーで制御 • Cache-Control ヘッダーでキャッ シュの挙動を制御 • ETag ヘッダーはコンテンツの全体や一 部を特定する固有値を示す ◦

    If-None-Match リクエストヘッ ダーと対で使われ、一致しない場 合のみコンテンツを返却するように サーバに指示 @postman_japan https://web.dev/articles/http-cache no-store no-cache キャッシュ期限を設けるか max-age=... ETag ヘッダーを使う レスポンスは再利用可能か はい いいえ 中間キャッシュを有効にするか private public 毎回検証が必要か はい いいえ いいえ はい
  20. 認証・認可 • どの認証・認可を使うべきか ◦ API 利用時に認証を求めるか ◦ 認可をどのように実装するか (認可情報をトークンに内包するか) @postman_japan

    認可方式 特徴 API キー 期限の長いトークン、認可テーブルを都度確認 OAuth 2.0 + 識別子 期限の短いトークン、認可サーバーに都度問い合わせ OAuth 2.0 + JWT 期限の短いトークン、トークンに認可情報が内包
  21. CORS(オリジン間リソース共有) • どの Web サイトが API を使用できるかを制御する。いくつかのタイプの攻撃を阻 止するのに役立つ • CORS

    ルールを返すレスポンスヘッダー @postman_japan CORS ルール 使用するヘッダー どのウェブサイトが API を使用できるか Access-Control-Allow-Origin API でできること Access-Control-Allow-Methods リクエストに含めることができる情報 Access-Control-Allow-Headers これらのルールを覚えておく期間 Access-Control-Allow-Age
  22. レートリミット • ユーザーまたはアプリ単位で単位時間あたりの API アクセス上限を設定 • 上限に達した時のステータスコードは「429 Too Many Requests」

    • ヘッダーでレートリミットの情報をユーザーに伝えるのがデファクト標準 @postman_japan ヘッダー名 説明 X-RateLimit-Limit 単位時間あたりのアクセス上限 X-RateLimit-Remaining 残り回数 X-RateLimit-Reset アクセス回数がリセットされるタイミング
  23. まとめ:代表的なガイドライン • API エンドポイントには明確で一貫性のある名前を使う • エンドポイントが何をするかに基づいて正しい HTTP メソッドを使用する • API

    がデータを正しく受け取り、応答できるように設計する • 必須情報にはパラメーターを使い、追加情報にはクエリ文字列を使う • よく使うデータをキャッシュして API を高速化する • 目的にあった認証・認可方式を選定 • API の使い方を明確かつ詳細に説明するドキュメントを作る @postman_japan
  24. OpenAPI 仕様 OAS OpenAPI(最新は2021年2月リリースの3.1)は、RESTful API を記述するための API 標準仕様で、API 定義 の詳細を人間とコンピュータが理解できるような形式で提供

    info メタデータ (バージョン、タイトル、ライセンス ) OpenAPI Specification 3.1 webhooks tags externalDocs 記述形式:JSON、YAML @postman_japan servers APIサーバーURLや環境 security 認証認可 OAuth2, APIキー) paths APIエンドポイント、 HTTPメソッドなど定義 components 再利用可能なスキーマ、リクエスト・レスポンスモデルなど • 目的: API の設計・ドキュメントの標準化、 API構 造定義に焦点 • 内容: API のメタ情報、パラメータ、リクエスト・レス ポンス情報、認証・認可情報など • 機械可読形式であるため、 API の設計、ドキュメ ント作成、テスト、モック、クライアントやサーバー の自動生成を容易にする
  25. Postman コレクション = 実行可能 API ドキュメント • コレクション は API

    リクエストをグループにして整理した、基本となるデータ構造 • コレクションを一言でいうと、実行可能な API ドキュメント コレクション APIリクエスト テスト サンプル APIリクエスト テスト サンプル APIリクエスト テスト サンプル @postman_japan