オライリー・ジャパンの『Web API: The Good Parts』を読みました。
「使いやすいWeb APIとは何か?」という視点で、設計の基本や実践的な考え方が整理されており、実務に関わる人にとって再確認にも学びにもなる内容だと感じました。
ここでは、特に印象に残ったポイントを、自分なりの解釈とともに紹介していきます。
はじめに
API設計について体系的に学ぶ機会がこれまで少なく、実務の中で必要に迫られることが増えてきたタイミングで、上司から「この本を読んでおくと良い」と勧められ、手渡されたのがきっかけで本書に触れました。
本書は少し古い内容ではあるもののWeb APIの設計と運用において、本質的に重要なポイントがコンパクトにまとめられており、実務にも役立つ知見が得られました。
発行から少し年数が経っているものの、Web APIの設計と運用における本質的な考え方がコンパクトに整理されており、実務においても十分に参考になる内容が多く含まれていました。
私は、以下の2点について知見を深めることを意識して、本書を読み進めることにしました。
- 美しいAPI設計とはなにか
- APIの更新情報はどのように管理するのか
美しいAPI設計とはなにか
API設計においてもですが「美しさ」とは、開発者にとっての使いやすさや分かりやすさ、保守性の高さなどが重要な指標になります。
本書を読んで特に印象に残ったのは、以下の4つのポイントでした
直感的でわかりやすい
たとえば members というエンドポイントを見ただけで、「メンバー情報を扱うリソースである」とすぐに理解できる設計は理想的だということです。
たとえば以下のようなURIであれば、何が得られるのかが直感的に想像できます。
- GET /members:メンバー一覧を取得
- GET /members/123:IDが123のメンバー詳細を取得
- POST /members:新しいメンバーを作成
このように、扱うデータの種類を軸にURIを設計し、操作の違いはURIではなくHTTPの動作で区別するようにすると、使う人にとって分かりやすい構成になります。
どのURIで何ができるのかが直感的に伝わるため、迷わず使えて、結果的にAPI全体の使いやすさが向上します。
一貫性がある
リソース名の命名やクエリパラメータの構造、レスポンスの形式が統一されていると、API全体に一貫性が生まれます。
一貫性があることで「このAPIはきっとこうなっているだろう」という予測が立てやすくなり、開発者が初めて触れる場合でもスムーズに理解し、使い始めることができます。
たとえば、以下のように命名ルールがバラバラだと混乱の原因になります。
友達の情報を取得
http://api.example.com/members?id=100
メッセージを投稿
http://api.example.com/member/100/message
ここでは「members」と「member」で複数形と単数形が混在しており、こうした不統一は見た目の悪さだけでなく、使用時の混乱を引き起こします。
また、以下のように大文字が含まれていたり、キャメルケースで書かれていたりするURIも避けるべきです。
http://api.example.com/API/getUserName
このような表記は、細かなスペルミスや環境による差異によって不具合の原因になりやすいため、すべて小文字で統一することが推奨されます。
さらに、getUserName
のようなキャメルケースを get-user-name
のようなスネークケースに置き換えれば良いかというと、そうではありません。
そもそもこのような長く複雑な単語の使用を避けるべきで、たとえば http://api.example.com/v1/users/:id
のように、直感的で構造が明確なエンドポイント設計を心がけることが重要です。
エラー設計が丁寧
API設計において、エラー時のレスポンスがわかりやすく設計されていることは非常に重要です。単にHTTPステータスコードを返すだけでは、エラーの種類は分かっても、具体的な原因や解決のヒントまでは分かりません。開発者が原因を素早く特定し、正しく対応できるように、具体的なエラー情報をレスポンス本文に含める設計が求められます。
まず、HTTPステータスコードはエラーの種類を示すものです。代表的な分類は以下の通りです。
ステータスコード | 意味 |
---|---|
100 番台 | 処理継続などの情報レスポンス |
200 番台 | リクエスト成功を示すレスポンス |
300 番台 | リダイレクト(別のURLへ誘導) |
400 番台 | クライアント側のエラー |
500 番台 | サーバー側のエラー |
ただし、これらのコードが表すのはあくまでエラーの大まかな分類や状態に過ぎません。たとえば 400 Bad Request と返ってきても、それが「パラメータが欠けている」のか「形式が間違っている」のかまでは分かりません。
そのため、エラーの詳細をクライアントに伝える仕組みが必要です。手法としては主に以下の2つがあります。
1. レスポンスヘッダにエラー情報を含める
簡易的なエラー情報を伝える場合には、HTTPヘッダに独自のキー(カスタムヘッダ)を使ってエラー内容を付加することがあります。たとえば以下のような形式です。
簡易的な情報を伝える場合に用いられます。
HTTP/1.1 400 Bad Request
X-Error-Code: VALIDATION_ERROR
X-Error-Message: name は必須です
この例では、HTTPステータスコード 400 Bad Request(不正なリクエスト)に加えて、X-Error-Code
というカスタムヘッダで「VALIDATION_ERROR」というアプリケーション固有のエラーコードを伝え、X-Error-Message
によって具体的なメッセージ「name は必須です」を返却しています。
この手法は、軽量かつシンプルな通知に適していますが、複数のエラー情報や構造的なデータを返すには不向きです。そのため、詳細な情報を伝える必要がある場合は、次に紹介するようにレスポンスボディにエラー情報を含める方法が推奨されます。
2. レスポンスボディで詳細な情報を返す
こちらのほうが最も一般的で、クライアントがパースしやすく、UIへのフィードバックにも使いやすい形式です。
{
"error": {
"code": "VALIDATION_ERROR",
"message": "name は必須です",
"field": "name"
}
}
このようにレスポンス本文にエラーコード(アプリ独自の識別子)や詳細メッセージ、該当フィールドなどを含めることで、フロントエンド開発者がエラーを正確に把握でき、適切なエラーメッセージの表示や処理が可能になります。
効率的なデータ設計
APIのレスポンス形式としては、一般的にJSONが使われます。現在では多くのシステムやフロントエンドがJSONを前提に設計されており、事実上の標準といえます。ただし、業務要件や既存システムとの連携など、必要に応じてXMLを採用するケースもあります。
また、データの構造設計においては、APIへのアクセス回数をなるべく減らすことが非常に重要です。アクセス回数が多くなると、ネットワーク通信が増え、アプリケーションのパフォーマンス低下やサーバー負荷の増大を招くためです。
ここでは、メンバー一覧を取得するAPIを例に考えてみます。
避けたい例
{
"members": [
11111,
22222,
33333,
44444,
]
}
この形式では、各メンバーのIDだけが返されます。データ量は少なくシンプルである反面、名前や役職、アイコンなどの詳細情報を取得するには、IDごとに個別のAPIを呼び出す必要があります。
たとえば:
GET /members/11111
といったリクエストが発生し、実装も運用も煩雑になります。
推奨される例
{
"members": [
{
"id": 11111,
"name": "yamautchi",
"role": "Engineer",
"icon": "gorilla"
},
{
"id": 22222,
"name": "ebisawa",
"role": "Engineer",
"icon": "cat"
},
{
"id": 33333,
"name": "morita",
"role": "Engineer",
"icon": "sheep"
},
{
"id": 44444,
"name": "morita",
"role": "Engineer",
"icon": "penguin"
}
]
}
この形式であれば、1回のリクエストで必要な情報をすべて取得できるため、追加のAPI呼び出しが不要になります。結果として、通信コストを抑えつつ、扱いやすく拡張性にも優れたAPIになります。利用者にとっても実装が簡潔になり、全体の開発効率が向上します。
APIの更新情報はどのように管理するのか
本書では「一度公開したAPIは原則として変更しないこと」が最善の策とされています。
これは、すでに使っているクライアントに影響を与えないようにするための基本的な考え方です。
とはいえ、サービスの改善や仕様変更が避けられない場面もあります。
その場合は、次のようなアプローチが推奨されています
- 新しいAPIエンドポイントの作成
- URIにパラメータを付与して別物として扱う
といった方法で、新しい形で再公開するのが推奨されています。
バージョニングについて
APIは運用が続く中で、機能追加や仕様変更が避けられません。
その際に重要になるのが、既存の利用者に影響を与えずに変更を反映できるようにする「バージョン管理」です。
一般的に最も広く使われているのは、URIにバージョン番号を含める方法です。
/api/v1/users
この形式は、クライアントがどのバージョンを使っているのかを明確に把握でき、サーバー側でも処理を分岐しやすいため、実務でもよく採用されています。
一方で、以下のような日付ベースのバージョン指定も一部では見られます。
/api/2023-03-01/users
この形式はリリース日を明示できる反面、
- URIが長く、扱いづらい
- 古いバージョンに見えてしまう
- 意味が伝わりにくい
といった理由から、一般的なAPI設計ではあまり推奨されません。
また、バージョンを増やしすぎることにも注意が必要です。
バージョンを増やしすぎると、コードやドキュメントが複雑になり、保守や運用の手間が増えます。
そのため、できるだけ既存の仕様を壊さずに対応し、本当に必要なときだけバージョンを分けるのが安全です。
まとめ
本書は、API設計の基本がしっかり押さえられていて、実務にもすぐ活かせる内容が詰まっていると感じました。ボリュームも過不足なく、最後までスムーズに読み進められる一冊でした。
この記事では取り上げませんでしたが、第6章のセキュリティに関する内容もとても参考になりました。セキュリティは日々の開発の中で見落とされがちな部分ですが、APIを安全に設計・運用するうえで欠かせない知識だと改めて実感しました。
API設計に関わるすべてのエンジニアにとって、読んでおいて損のない一冊だと思います。初学者にも経験者にもおすすめできると感じました。