API と契約
明確な契約を通じて、バックエンド API がどのように設計され、構造化され、保守されるかの概要。
APIとは実際に何か
API(Application Programming Interface)は、クライアントがバックエンドシステムと通信し、システムの機能にアクセスするためのインターフェースです。
- APIはシステムの機能を公開し、外部のクライアントがバックエンドとやり取りできるようにします。
- Webアプリ、モバイルアプリ、その他のサービスなどのクライアントは、APIにリクエストを送信します。
- APIは、リクエストの構造と、サーバーから返されるレスポンスの形式を定義します。
詳細
現代のソフトウェアシステムでは、アプリケーションがバックエンドのロジックと直接やり取りすることはほとんどありません。代わりに、APIを通じて通信します。APIは、システムへの制御された प्रवेश口として機能します。
クライアント — たとえばブラウザ、モバイルアプリケーション、または別のバックエンドサービス — は、特定のAPIエンドポイントにリクエストを送信します。APIはそのリクエストを受け取り、含まれている情報を解釈し、適切なバックエンドロジックへ渡します。その後、バックエンドはデータベースからのデータ取得やアプリケーションルールの実行など、必要な処理を行い、レスポンスをクライアントに返します。
このような構造化された通信により、システムはモジュール化された状態を保てます。フロントエンドアプリケーション、モバイルアプリ、外部サービスは、APIで定義されたリクエストとレスポンスの形式に従う限り、同じバックエンド機能とやり取りできます。
APIは、リクエストをどのように構造化する必要があるか、そしてレスポンスがどのような見た目になるかを定義するため、システムの異なる部分の間に予測可能なインターフェースを作ります。このインターフェースにより、内部のバックエンド実装がどのように動作しているかを知らなくても、個別に開発されたコンポーネント同士が信頼性高く通信できます。
HTTPメソッド
HTTPメソッドは、クライアントが API エンドポイントとやり取りするときに実行したい操作の種類を定義します。
- HTTPメソッドは、リクエストで意図するアクションを伝えます。
- 異なるメソッドは、リソースに対する異なる操作に対応します。
- API は HTTPメソッドをエンドポイントと組み合わせて、システムの動作を定義します。
詳細
クライアントが API エンドポイントにリクエストを送るときは、どの種類の操作を実行したいのかを指定する必要があります。この操作は HTTPメソッドで表されます。
HTTPメソッドは、エンドポイントの URL と組み合わさって、リクエストの意味を定義します。
たとえば、GET /users のようなリクエストは、サーバーにユーザーデータの取得を求めます。POST /users のようなリクエストは、新しいユーザーの作成をサーバーに求めます。DELETE /users/42 のようなリクエストは、バックエンドに特定のユーザーの削除を指示します。
API では、いくつかの HTTPメソッドが一般的に使われます。
GET は、サーバーから既存のデータを取得します。
POST は、新しいリソースを作成します。
PUT は、既存のリソースを新しいデータで置き換えます。
PATCH は、既存のリソースの一部を更新します。
DELETE は、システムからリソースを削除します。
エンドポイントと HTTPメソッドを組み合わせることで、API はクライアントがシステムのリソースに対して実行できる操作を明確に定義します。
REST とリソースベース API
REST (Representational State Transfer) は、システムがアクションではなくリソースを公開する、一般的な API 設計アプローチです。
- REST API は、ユーザー、注文、商品などのリソースを中心にエンドポイントを整理します。
- 操作は、アクションベースの URL ではなく HTTP メソッドを使って定義されます。
- リソースベースの設計により、より一貫性があり予測しやすい API になります。
詳細
API 設計では、エンドポイントをアクション中心に構成する方法があります。この場合、各 URL はシステムが何をすべきかを表します。たとえば、POST /createUser のようなエンドポイントは、アクションを URL に直接埋め込んでいます。
この方法は小規模なシステムでは機能しますが、機能数が増えると保守が難しくなります。エンドポイントの一貫性が失われ、新しい機能がどのように公開されるのか予測しにくくなります。
REST は、ユーザー、注文、商品などのリソースを中心に API を整理することで、別のアプローチを取ります。URL にアクションを埋め込む代わりに、エンドポイントはリソースを表し、HTTP メソッドが操作を定義します。
たとえば、POST /users は新しいユーザーを作成し、GET /users はユーザーを取得します。この分離により、API 全体で一貫したパターンが生まれます。
この構造のおかげで、RESTful API は理解しやすく、スケールしやすく、拡張もしやすくなります。新しいエンドポイントも、同じ予測しやすい設計に従っているため、開発者はより簡単に扱えます。
RESTの原則
REST APIs は、システムを予測しやすく、スケーラブルにし、保守しやすくする一連の原則に従います。
- リクエストはステートレスであり、各リクエストに必要な情報がすべて含まれます。
- リソースは、一貫性があり構造化された URL を使って識別されます。
- HTTP メソッドは、操作を表すために正しく使用されます。
- API は、統一され予測可能なインターフェース設計に従います。
詳細
REST は、システムが大きくなっても API の一貫性と信頼性を保つための設計原則に基づいています。
重要な原則の 1 つは、ステートレスな通信です。各リクエストには、サーバーが処理するために必要なすべての情報が含まれていなければなりません。サーバーは以前のリクエストに依存しないため、システムのスケールや分散がしやすくなります。
もう 1 つの原則は、リソースベースの設計です。API はユーザーや注文などのエンティティをリソースとして表現し、これらのリソースは /users や /orders のような URL で識別されます。
REST は標準的な HTTP の意味論にも依存しています。GET、POST、PUT、PATCH、DELETE などの HTTP メソッドは、リソースに対して行われる操作を明確に表すために使用されます。
最後に、REST は統一されたインターフェースを強制します。エンドポイントは一貫したパターンに従うため、API を理解しやすくなり、システムのさまざまな部分を扱う際の混乱を減らせます。
ステータスコード
HTTPステータスコードにより、サーバーはリクエストの結果を標準化された予測可能な方法で伝えることができます。
- ステータスコードは、リクエストが成功したのか、クライアントの入力が原因で失敗したのか、サーバー側の問題で失敗したのかを示します。
- これらは先頭の数字に基づいてカテゴリ分けされています。
- クライアントは、レスポンスをどのように処理するかを判断するためにステータスコードに依存します。
詳細
サーバーがリクエストを処理するとき、その結果をクライアントに返す必要があります。HTTPステータスコードは、その結果を標準化された方法で表すために使われます。
ステータスコードはカテゴリごとに分かれています。2xxの範囲のコードは成功を示し、リクエストが正しく処理されたことを意味します。4xxの範囲のコードは、無効な入力やリソースの不足などのクライアントエラーを示します。5xxの範囲のコードはサーバーエラーを示し、バックエンドで何か問題が発生したことを意味します。
一般的な例としては、成功したリクエストを示す 200 OK や、新しいリソースが作成されたことを確認する 201 Created があります。400 Bad Request のようなエラーは無効な入力を示し、401 Unauthorized は認証情報がない、または無効であることを示します。404 Not Found のレスポンスは要求されたリソースが存在しないことを意味し、500 Internal Server Error はサーバー側での失敗を示します。
クライアントは、これらのステータスコードを使って次にどう進むかを判断します。たとえば、サーバーエラーの後にリクエストを再試行したり、クライアントエラーの後にユーザーへ入力の修正を促したりします。
冪等性
ある操作は、同じリクエストを繰り返しても、追加の副作用を起こさずに同じ結果になる場合、冪等です。
- 冪等な操作は、結果を変えずに安全に繰り返すことができます。
- PUT と DELETE は通常冪等ですが、POST は通常そうではありません。
- 冪等性は、再試行やネットワーク障害を扱ううえで重要です。
詳細
分散システムでは、リクエストが失敗したり、タイムアウトしたり、複数回再試行されたりすることがあります。そのため、バックエンドシステムは繰り返し送られるリクエストを安全に処理できるように設計する必要があります。
ある操作は、同じリクエストを複数回送っても最終状態が同じであれば、冪等とみなされます。たとえば、DELETE /users/10 を1回呼び出すと、そのユーザーは削除されます。もう一度呼び出しても、そのユーザーはすでに削除されているため、それ以上は何も変わりません。
同様に、PUT /users/10 は毎回同じデータでリソースを置き換えるため、リクエストを繰り返しても追加の副作用は発生しません。
一方で、POST /orders は通常冪等ではありません。なぜなら、各リクエストが新しい注文を作成するからです。同じリクエストを繰り返すと、重複したリソースが作成される可能性があります。
冪等性が重要なのは、障害が発生したときにシステムがリクエストを自動的に再試行することが多いためです。冪等性がなければ、再試行によってデータの不整合、操作の重複、または意図しない副作用が発生する可能性があります。
APIのバージョニング
APIのバージョニングにより、バックエンドシステムは既存のクライアントを壊すことなく進化できます。これは、APIの複数のバージョンを維持することで実現されます。
- APIへの変更は、古い動作に依存しているクライアントを壊す可能性があります。
- バージョニングにより、複数のAPIバージョンを安全に共存させることができます。
- クライアントは、どのバージョンのAPIとやり取りするかを選択できます。
詳細
バックエンドシステムが進化するにつれて、APIも変更が必要になることがよくあります。新しい機能が追加されたり、データ形式が更新されたり、既存の動作が変更されたりします。
問題は、Webアプリ、モバイルアプリ、サードパーティの連携などのクライアントが、既存のAPIの動作に依存していることです。APIが予告なく変更されると、それらのクライアントが壊れる可能性があります。
APIのバージョニングは、APIの複数のバージョンを同時に存在させることで、この問題を解決します。古いクライアントは元のバージョンを使い続けることができ、新しいクライアントは更新されたバージョンを採用できます。
一般的な方法の1つはURLバージョニングで、バージョンをパスに含めます。たとえば、/v1/users や /v2/users です。別の方法はヘッダーバージョニングで、クライアントが Accept: application/vnd.api.v2 のようなヘッダーを使ってバージョンを指定します。
APIをバージョニングすることで、バックエンドシステムは既存のクライアントとの互換性を保ちながら、安全に進化できます。
API契約
API契約は、クライアントとバックエンドシステムがどのように通信するかを定義し、リクエストとレスポンスが予測可能で信頼できる構造に従うことを保証します。
📍 エンドポイント
契約で定義された入口です。
- 契約は利用可能なエンドポイントと、そのアクセス方法を定義します。
- リクエストとレスポンスの構造を指定します。
- ステータスコードと動作の期待値が明確に定義されます。
詳細
API契約は、クライアントとバックエンドシステムの間の合意として機能します。両者が曖昧さなくやり取りできるように、通信をどのように行うべきかを正確に定義します。
クライアントが HTTP リクエストを送信するときは、正しいエンドポイントを使用し、期待されるデータ形式を提供し、必要な情報をすべて含めることで、この契約に従う必要があります。バックエンドシステムはこれらのルールに基づいてリクエストを処理し、構造化された HTTP レスポンスを返します。
この契約は、利用可能なエンドポイント、リクエストデータの形式、レスポンスの構造、ステータスコードの意味、各操作に期待される動作など、API のいくつかの重要な側面を定義します。
この契約があることで、クライアントはバックエンドが内部でどのように実装されているかを理解する必要がありません。定義されたインターフェースに従っている限り、通信は一貫して信頼できます。
実際には、API契約はフロントエンドチームとバックエンドチームの連携だけでなく、独立したシステム同士の統合においても不可欠です。
質問セクション
1 / 5
このレッスンはプレミアムコンテンツです
プレミアムにアップグレードしてぼかしを解除し、全文を読めるようにしましょう。