API連携の羅針盤!API Gatewayで作るセキュアで高機能なAPI
こんにちは!現役エンジニアのakrです。
「【AWSプロフェッショナルへの道】現役エンジニアが贈るクラウド実践ガイド」の第11回をお届けします。前回はAWS Lambdaでサーバーレス開発の基本を学び、サーバー管理から解放される喜びを感じられたのではないでしょうか。API GatewayとLambdaを組み合わせることで、まさに「サーバーレスAPI」の完成形が見えてきましたね。
今回は、そのAPI Gateway (Amazon API Gateway) を深掘りします。API Gatewayは、RESTful APIやWebSocket APIを簡単に作成、公開、保守、監視できるフルマネージドサービスです。前回はLambdaと連携してシンプルなWeb APIを構築しましたが、API Gatewayにはそれ以外にもセキュリティ、スケーリング、トラフィック管理、モニタリングといった、API運用に不可欠な多くの高機能が備わっています。
「APIってどうやって守るの?」「大量のリクエストを捌くには?」「複数のバックエンドを統合したい」といった悩みを、API Gatewayがどのように解決してくれるのかを学びましょう。本記事では、API Gatewayの基本概念から、APIの種類、メソッド、統合タイプ、認証認可、スロットリング、CORS設定までを網羅的に学び、実践的なAPI設計と運用スキルを身につけます。
1. API Gatewayとは?なぜAPI Gatewayが必要なのか?
API Gateway (Amazon API Gateway) は、Webアプリケーション、モバイルアプリケーション、IoTデバイスなど、さまざまなクライアントからのリクエストを、バックエンドのAWSサービス(Lambda、EC2、DynamoDBなど)やオンプレミスシステムにルーティングする「APIの玄関口」として機能します。
なぜAPI Gatewayが必要なのか?
API Gatewayは、単なるリクエストの転送役ではありません。APIを運用する上で発生する様々な課題を解決し、開発者はビジネスロジックの実装に集中できるようになります。
- フロントドアの役割: 多数のクライアントからのリクエストを単一のエンドポイントで受け付け、適切なバックエンドにルーティングします。
- セキュリティの強化: APIキー、IAM、Cognito、Lambdaオーソライザーなど、多様な認証・認可オプションを提供し、不正なアクセスからAPIを保護します。
- トラフィック管理とスケーリング: 大量の同時リクエストを処理するための自動スケーリング機能や、スロットリング(過剰なリクエスト制限)設定により、バックエンドの過負荷を防ぎます。
- キャッシュ機能: レスポンスをキャッシュすることで、バックエンドへの負荷を軽減し、APIの応答速度を向上させます。
- リクエスト/レスポンスのマッピング: クライアントからのリクエストやバックエンドからのレスポンスの形式を変換し、柔軟なデータ連携を可能にします。
- バージョン管理とデプロイ: APIの複数のバージョンを管理し、異なるステージ(開発、ステージング、本番)にデプロイできます。
- モニタリングとログ: APIへのアクセス状況、パフォーマンス、エラーなどを詳細に監視し、CloudWatchと連携してログを記録します。
- CORS (Cross-Origin Resource Sharing) のサポート: Webブラウザからのクロスオリジンリクエストに対応できます。
2. API Gatewayの主要な種類と構成要素
API Gatewayには主に3つのタイプがあります。
2.1. API Gatewayの主要な種類
-
REST API:
- RESTfulなWebサービスを構築するための標準的なAPIです。
- HTTPメソッド(GET, POST, PUT, DELETEなど)とリソースパス(
/users/{id}など)を使用して操作を定義します。 - 以前は「エッジ最適化」と「リージョン」の2種類がありましたが、現在は単一のREST APIとして提供され、デプロイ時にエッジ最適化かリージョンかを選択します。
- 用途: 一般的なWeb API、モバイルバックエンドなど。
-
HTTP API:
- REST APIよりも低レイテンシー、低コストで、基本的なAPI機能に特化した新しいタイプのAPIです。
- よりシンプルで、GET/POSTなどの基本的なHTTPメソッドに迅速に対応したい場合に適しています。
- REST APIの一部の高度な機能(カスタムオーソライザーのCache-Control、リクエスト検証、WAF統合など)はサポートしていません。
- 用途: シンプルなAPI、サーバーレスアプリケーションのバックエンドなど、パフォーマンスとコストを重視する場合。
-
WebSocket API:
- リアルタイム双方向通信を必要とするアプリケーション(チャットアプリ、ゲーム、リアルタイムダッシュボードなど)を構築するためのAPIです。
- WebSocketプロトコル(ws://またはwss://)を使用します。
- 用途: チャットアプリケーション、ライブフィード、IoTデバイスとの双方向通信など。
本記事では、最も広く利用されているREST APIを中心に解説を進めます。
2.2. API Gatewayの構成要素
- API (Application Programming Interface): 複数のリソース、メソッド、統合ポイントの集合体です。
-
リソース (Resource): APIの操作対象となるURIパスの一部です(例:
/users,/products/{id})。 - メソッド (Method): リソースに対して実行されるHTTPメソッド(GET, POST, PUT, DELETE, PATCH, OPTIONSなど)です。
-
統合リクエスト/レスポンス (Integration Request/Response): API Gatewayとバックエンドサービス(Lambda、EC2、HTTPエンドポイントなど)間のデータの変換を定義します。
- 統合タイプ: バックエンドサービスの種類(Lambda関数、HTTPプロキシ、AWSサービス、VPCリンクなど)を指定します。
- メソッドリクエスト/レスポンス (Method Request/Response): クライアントとAPI Gateway間のデータの形式を定義します。リクエストの検証や、レスポンスの変換ルールを設定できます。
-
デプロイステージ (Deployment Stage): APIの特定のバージョンを公開する環境(例:
dev,staging,prod)です。 - APIキー (API Key): APIへのアクセスを制御するためのキーです。使用量プランと組み合わせて利用されます。
- 使用量プラン (Usage Plan): APIキーごとに、APIへのアクセスレート(リクエスト数/秒)とクォータ(指定期間内の合計リクエスト数)を制限します。
- オーソライザー (Authorizer): APIへのアクセスを認証・認可するためのカスタムロジックです(Lambdaオーソライザー、Cognitoユーザープールオーソライザーなど)。
3. 実践!セキュアなWeb APIをAPI Gatewayで構築しよう
前回の記事で作成したLambda関数をバックエンドとし、API GatewayでAPIキーによるアクセス制御を設定したWeb APIを構築してみましょう。
3.1. REST APIの作成とリソース/メソッド定義
前回作成したLambda関数(my-simple-api-function)を統合するAPIを作成します。
-
AWSマネジメントコンソールにサインインし、「API Gateway」サービスに移動します。
-
左のナビゲーションペインから「API」を選択し、「APIを作成」をクリックします。
-
REST APIの「構築」をクリックします。
-
REST APIを作成:
-
API名:
MySecureWebAppAPI -
説明:
A secure API for my web application - エンドポイントタイプ: 「リージョン」を選択します。(今回はリージョンで十分ですが、グローバルな分散が必要な場合は「エッジ最適化」を選択)
- 「APIを作成」をクリック。
-
API名:
-
リソースの作成:
- 左側のナビゲーションで作成したAPI(
MySecureWebAppAPI)が選択されていることを確認します。 - 「アクション」→「リソースを作成」をクリックします。
-
リソース名:
hello - 「リソースの作成」をクリック。
- 左側のナビゲーションで作成したAPI(
-
メソッドの作成:
- 作成したリソース(
/hello)が選択されていることを確認します。 - 「アクション」→「メソッドを作成」をクリックします。
- メソッドタイプ: 「GET」を選択します。
- 統合タイプ: 「Lambda 関数」を選択します。
- Lambdaプロキシ統合の使用: チェックを入れます。(Lambda関数にHTTPイベント全体を渡し、Lambdaが直接HTTPレスポンスを返すようにするため)
-
Lambda関数: 前回作成したLambda関数名(
my-simple-api-function)を入力し、ドロップダウンから選択します。 - 「保存」をクリック。
- Lambda関数へのAPI Gatewayのアクセス許可が求められるので、「OK」をクリック。
- 作成したリソース(
これでAPI GatewayとLambda関数の基本的な連携が完了しました。
3.2. APIキーによるアクセス制御の設定
APIにAPIキーによる認証をかけ、許可されたクライアントのみがAPIにアクセスできるようにします。
-
MySecureWebAppAPIの/helloリソースのGETメソッドが選択されている状態で、「メソッドリクエスト」をクリックします。 -
APIキーの必須設定: 「承認」セクションの「APIキーの必須設定」の右にある鉛筆アイコンをクリックします。
- ドロップダウンから「true」を選択し、チェックマークをクリックして保存します。
これで、このAPIメソッドにアクセスするにはAPIキーが必要になります。
3.3. APIキーと使用量プランの作成
APIキーを発行し、そのキーに紐づく使用量プランを設定します。
- 左のナビゲーションペインから「APIキー」を選択し、「APIキーを作成」をクリックします。
-
名前:
my-test-api-key - 「自動生成」のままで「作成」をクリック。
- 作成されたAPIキーの「APIキーの値」をコピーします。(後でAPIアクセス時に使用します)
- 左のナビゲーションペインから「使用量プラン」を選択し、「使用量プランを作成」をクリックします。
-
名前:
my-test-usage-plan -
スロットリング:
-
レート:
10(1秒あたり最大10リクエスト) -
バースト:
20(一時的に最大20リクエストまでバースト可能)
-
レート:
-
クォータ:
-
制限:
1000 -
単位:
月間
-
制限:
- 「次へ」をクリック。
-
APIステージを関連付ける:
-
API:
MySecureWebAppAPI - ステージ: (まだステージがないので、後で作成します) → 「次へ」をクリック。
-
API:
-
APIキーを関連付ける:
- 「APIキーを追加」をクリックし、先ほど作成した
my-test-api-keyを選択します。 - 「次へ」をクリック。
- 「APIキーを追加」をクリックし、先ほど作成した
- 「作成」をクリック。
3.4. APIのデプロイ
設定したAPIをステージにデプロイすることで、外部からアクセス可能になります。
-
MySecureWebAppAPIの画面に戻り、「アクション」→「APIのデプロイ」をクリックします。 -
デプロイステージ: 「新しいステージ」を選択します。
-
ステージ名:
v1(またはdev,prodなど)
-
ステージ名:
- 「デプロイ」をクリック。
デプロイが完了すると、v1ステージのエンドポイントURLが表示されます。
3.5. Web APIにアクセスしてみよう
デプロイされたAPIに、APIキーを使ってアクセスしてみましょう。
-
デプロイされたステージ(
v1)のエンドポイントURLをコピーします。- 例:
https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/hello
- 例:
-
APIキーなしでアクセス:
- WebブラウザでこのURLに直接アクセスしてみてください。
-
{"message":"Forbidden"}または{"message":"Missing Authentication Token"}のようなエラーが表示されるはずです。これは、APIキーが必須に設定されているため、キーなしではアクセスできないことを示しています。
-
APIキーを使ってアクセス:
- APIキーはHTTPヘッダーの
x-api-keyとして渡す必要があります。 -
curlコマンドを使ってアクセスしてみましょう。<APIエンドポイントURL>と<コピーしたAPIキーの値>を置き換えて実行してください。
curl -X GET -H "x-api-key: <コピーしたAPIキーの値>" <APIエンドポイントURL>例:
curl -X GET -H "x-api-key: your-generated-api-key-value-xxxxxxxx" https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/hello{"message":"Hello from Lambda!","receivedEvent":{...}}のようなJSONレスポンスが表示されれば成功です! - APIキーはHTTPヘッダーの
4. API Gatewayのその他の機能とベストプラクティス
API Gatewayには、今回紹介しきれなかった多くの高機能があります。
その他の機能
- Lambdaオーソライザー (旧カスタムオーソライザー): Lambda関数を使って、独自の認証・認可ロジックを実装できます。JWTトークンの検証やデータベースでのユーザー認証など、複雑な認証に対応可能です。
- Cognitoユーザープールオーソライザー: Amazon Cognito User Poolと連携し、ユーザー認証・認可を簡単に行えます。
- VPCリンク: API GatewayからVPC内のプライベートなリソース(ALB、NLB、EC2インスタンスなど)に安全にアクセスできます。インターネットに公開されていないバックエンドへの統合に利用します。
- AWS WAFとの統合: Webアプリケーションファイアウォール (WAF) をAPI Gatewayの前段に配置し、SQLインジェクションやクロスサイトスクリプティング(XSS)などの一般的なWeb攻撃からAPIを保護できます。
- キャッシュ設定: APIレスポンスをキャッシュすることで、バックエンドへの負荷を軽減し、レイテンシーを改善します。
- リクエスト検証: APIスキーマを定義し、クライアントからのリクエストがそのスキーマに準拠しているかをAPI Gateway側で検証できます。
- モニタリングとCloudWatch: APIの呼び出し回数、レイテンシー、エラー率などのメトリクスをCloudWatchで詳細に監視できます。ログの記録も可能です。
- CORS (Cross-Origin Resource Sharing): Webブラウザからのクロスオリジンリクエストを許可するためのヘッダーを自動的に追加する設定が可能です。
ベストプラクティス
- 最小特権の原則: API GatewayがバックエンドのLambda関数や他のAWSサービスにアクセスするIAMロールには、必要最小限の権限のみを付与しましょう。
- 適切な統合タイプの選択: Lambda関数をプロキシ統合で使用するか、カスタム統合で使用するか、HTTPプロキシ統合を使用するかなど、ユースケースに合わせて適切な統合タイプを選択しましょう。
- 認証・認可の徹底: 本番環境では、APIキーだけでなく、LambdaオーソライザーやCognitoユーザープールオーソライザーなど、より強力な認証・認可メカニズムを導入しましょう。
- スロットリングとクォータの設定: API Gatewayに適切なスロットリングとクォータを設定することで、バックエンドへの過負荷を防ぎ、APIを安定稼働させましょう。
- エラーハンドリング: API Gatewayレベルでエラーレスポンスをカスタマイズし、クライアントに分かりやすいエラーメッセージを返すようにしましょう。
-
カナリアリリースとステージ: 新しいバージョンのAPIを一部のユーザーに限定してリリースする「カナリアリリース」を実装し、リスクを低減しましょう。また、
dev,staging,prodなどのステージを適切に活用しましょう。 - CloudFormation (IaC) で管理: API Gatewayの設定もCloudFormationテンプレートとして管理し、変更履歴の追跡や環境間の一貫性を確保しましょう。
まとめ
今回は、API連携の要となるAmazon API Gatewayについて、その多機能性と実践的な使い方を学びました。
- API Gatewayは、APIの玄関口として機能し、セキュリティ、スケーリング、トラフィック管理、モニタリングなど、API運用に必要な多くの機能を提供します。
- REST API、HTTP API、WebSocket APIの3種類のAPIタイプを理解しました。
- リソース、メソッド、統合、デプロイステージといった主要な構成要素を学びました。
- 実際にLambda関数をバックエンドとして、REST APIを作成し、APIキーによるアクセス制御を設定してデプロイ、テストを行いました。
API Gatewayを使いこなすことで、あなたは単にAPIを提供するだけでなく、安全で、スケーラブルで、管理しやすいWeb APIを構築できるようになります。これは、現代の分散型アプリケーションやマイクロサービスアーキテクチャにおいて非常に重要なスキルです。ぜひ、ご自身のアプリケーションでAPI Gatewayの様々な機能を試してみてください。
この記事が皆さんのAWS学習の一助となれば幸いです。
もしこの記事が役に立ったと感じたら、ぜひ「いいね」👍をお願いします!励みになります!