API Gateway・Lambda・DynamoDBによるHTTP APIの構築
API GatewayがHTTPリクエストをLambdaへルーティングし、DynamoDBの項目を作成・取得する流れと、認証、スロットリング、再試行を学びます。
API Gateway・Lambda・DynamoDBによるHTTP APIの構築
API Gateway、AWS Lambda、Amazon DynamoDBを組み合わせると、サーバーを常時稼働させずにHTTP APIを構築できます。API Gatewayはクライアントからの要求を受け付け、ルートやメソッドの設定に応じてLambda関数を呼び出します。Lambdaは入力を検証してアプリケーション処理を行い、必要に応じてDynamoDBの項目を作成したり読み取ったりします。処理結果はAPI Gatewayを経由してHTTPレスポンスとして返ります。
リクエストからデータベースまでの役割分担
たとえば、温室の環境センサーを管理するアプリケーションでは、運用担当者がセンサーの設置情報を登録し、あとから個別のセンサー情報を照会できます。クライアントはHTTPSでAPI Gatewayに要求を送り、API Gatewayは設定されたルートから対象のLambda関数へ処理を引き渡します。
各サービスの担当範囲を分けて理解しましょう。
- クライアントは、HTTPメソッド、URL、ヘッダー、必要に応じてJSON本文を組み立てます。
- API Gatewayは、公開するエンドポイント、ルートやメソッド、認証・認可設定などに基づいて要求を受け付け、バックエンドへ接続します。
- Lambdaは、イベントとして受け取ったパスや本文を読み取り、入力検証や業務ルールの適用を行ってDynamoDBを呼び出します。
- DynamoDBは、Lambdaからの読み書き要求に応じてテーブルの項目を保存または返却します。
Lambdaの実行ロールには、関数が操作するテーブルに対する必要最小限の権限を付与します。これは、API GatewayがLambdaを呼び出す許可とは別です。API Gatewayから関数を起動できるようにする許可と、関数からDynamoDBへアクセスするIAM権限をそれぞれ設定します。
POSTリクエストで項目を作成する
新しいセンサーを登録するとき、クライアントはエンドポイントに POST を送り、JSON形式の本文に登録情報を含めます。リクエストはHTTPSのエンドポイント、ヘッダー、本文から構成されます。たとえば本文には、センサーを識別するID、設置場所、測定対象などを含められます。
POST /sensors HTTP/1.1
Host: api.example.net
Content-Type: application/json
{
"sensorId": "sensor-7c2",
"site": "greenhouse-north",
"measurement": "humidity"
}
api.example.net はAPIのドメインを表す例示用の値です。実際のAPIでは、API Gatewayのエンドポイントまたは独自ドメインを使います。データ本文はJSONで送りますが、HTTPの Content-Type で形式も伝えます。
API Gatewayが POST /sensors をLambda関数へ統合する設定なら、関数は要求イベントから本文を取り出してJSONとして解析します。入力形式、必須属性、属性値の範囲を検証してから、DynamoDBの PutItem などを使って項目を保存します。主キーの値は、システムの設計に応じてクライアント、Lambda、または別のID発行処理で用意します。クライアントからIDを受け取る場合は、同一IDの登録を上書きしてよいのか、条件付き書き込みで重複を拒否するのかを決めておきます。
処理が成功したら、LambdaはAPI Gatewayとの統合形式に沿ってステータスコードと応答本文を返します。作成結果を 201 Created とJSONで返す設計や、受付を 200 OK または 202 Accepted で返す設計が考えられます。API Gatewayは統合応答をクライアント向けHTTPレスポンスとして返します。Lambdaプロキシ統合では、関数が返すオブジェクトのステータスコード、ヘッダー、本文をAPI GatewayがHTTP応答に反映するため、統合方式に合った形式で返す必要があります。
GETリクエストで項目を取得する
特定のセンサー情報を調べる場合、クライアントはセンサーIDをパスに含めた GET リクエストを送ります。API Gatewayのルートがパスパラメータを受け取り、取得用のLambda関数へ渡す構成です。
GET /sensors/sensor-7c2 HTTP/1.1
Host: api.example.net
Accept: application/json
Lambdaはイベントから sensor-7c2 の部分をパスパラメータとして取り出し、DynamoDBのテーブルキーに指定して GetItem などの読み取りを行います。項目が見つかれば、Lambdaは属性をJSON本文に整形して成功レスポンスを返します。対象が存在しない場合は 404 Not Found など、APIで定めた結果を返します。
ここで重要なのは、クライアントがDynamoDBを直接呼び出すのではなく、API GatewayがLambdaを呼び、Lambdaが実行ロールの権限でDynamoDBへアクセスすることです。クライアントが受け取るのはDynamoDB固有の応答ではなく、APIが定義したHTTPステータス、ヘッダー、JSON本文です。
認証情報とAPIキーを区別する
APIへの要求には、呼び出し元を認証したりアクセスを認可したりするための情報をヘッダーなどに含める場合があります。ただし、すべての「トークン」やキーが同じ役割を持つわけではありません。
REST APIのAPIキーは、使用量プランと組み合わせて呼び出し元を区別し、使用量や目標レートを管理するために使われます。APIキーを必須にするメソッドを設定し、発行したキーを使用量プランのAPIステージに関連付けます。クライアントは通常 x-api-key ヘッダーで値を送ります。APIキーを持っていること自体は、利用者の本人確認や個別データへのアクセス権を証明しません。APIキーだけを認証・認可の境界として使わないでください。
利用者を認証する要件には、APIタイプやクライアントに合わせてIAM認証とSigV4署名、CognitoユーザープールまたはJWTオーソライザー、Lambdaオーソライザーなどを選びます。たとえばBearerトークンを Authorization ヘッダーで送る場合、API Gateway側のJWT/Cognitoオーソライザーや独自の検証処理が、そのトークンを検証する構成が必要です。単に Authorization ヘッダーを付けただけで認証されるわけではありません。
APIキーやBearerトークンなどの秘密情報はHTTPSで送信し、ソースコードや公開アプリに長期の秘密値を埋め込まないようにします。ブラウザーやモバイルアプリに配置された値は利用者から確認され得るため、サーバー側の認証・認可と権限の範囲も適切に設計します。
スケーリング、スロットリング、429応答
API Gatewayはマネージドサービスとしてリクエスト量の変化に対応しますが、無制限にリクエストを処理するわけではありません。AWSアカウントやAPIの設定にはスロットリングクォータがあり、設定されたレートやバーストを超える呼び出しは拒否されることがあります。その場合、API Gatewayは一般に 429 Too Many Requests を返します。49 というHTTPステータスコードはなく、429や5xxなど実際のステータスとエラー元を確認して対処します。
スロットリングはトークンバケットの考え方で理解できます。一定の速度でトークンが補充され、短時間の突発的な呼び出しにはバースト容量の範囲で対応します。平均的な呼び出しレートと、一時的に許容できる集中量は別々に考えます。REST APIではアカウント、ステージ、メソッドなどの単位で設定でき、使用量プランを通じてAPIキー単位の目標値を設定することもできます。
代表的なリージョンでは、アカウント単位の既定スロットリング値が毎秒10,000リクエスト、バースト容量が5,000リクエストと案内されています。リージョンによっては既定値が毎秒2,500リクエスト、バースト1,250リクエストとなる場合もあります。したがって「毎秒1万リクエスト、バースト5万」を全APIに共通する固定保証として覚えるのは誤りです。API GatewayのクォータはAPIタイプ、リージョン、アカウントの現在のサービスクォータなどで変わり、クォータ引き上げの可否も条件によります。使用量プランのレートとクォータもベストエフォートであり、セキュリティ上の強制的な上限や厳密な課金上限としては扱えません。実際の制限値はAWS Service Quotasと該当APIの設定で確認します。
指数バックオフで再試行する
クライアントがスロットリングや一時的なサーバー障害を受けたとき、すぐに同じ要求を繰り返すと、混雑をさらに悪化させることがあります。指数バックオフでは、失敗後に待つ時間を徐々に延ばして再試行し、要求の集中を和らげます。複数のクライアントが同じ間隔で再送して再び集中するのを避けるため、待機時間にランダムな揺らぎ(ジッター)を加える方法も一般的です。
再試行対象は、429や一時的な5xx、ネットワークの一時障害などに絞ります。入力不備を示す4xxをそのまま再試行しても通常は成功しません。レスポンスに Retry-After が含まれる場合はその指示も考慮し、最大試行回数と全体のタイムアウトを設けます。
AWS SDKにはAWSサービスAPI向けの再試行モードがあり、スロットリングや一時エラーへの指数バックオフなどが実装されています。ただし、任意のAPI Gatewayエンドポイントを通常のHTTPクライアントで呼び出す場合に、SDKの再試行が自動的に有効になるとは限りません。利用するHTTPクライアントやSDKの対象サービス、再試行条件を確認し、必要ならアプリケーション側で制御します。
書き込み要求を再試行すると、最初の要求が成功した後に応答だけが失われていた場合、同じ処理が重複するおそれがあります。POSTを安全に再試行できるようにするには、冪等性キー、条件付き書き込み、重複検出などを設計します。指数バックオフは過剰な再送を抑える方法であり、操作の重複を自動で防ぐ機能ではありません。
DVA試験での確認ポイント
- クライアントのHTTP要求を受け付け、LambdaへルーティングするのがAPI Gateway。業務ロジックを実行してDynamoDBを読み書きするのがLambda。
- JSON本文を含む作成要求は一般にPOST、識別子で項目を取得する要求はGETを使う。パス、メソッド、本文などから必要な入力を取り出す。
- Lambdaの実行ロールによるDynamoDB操作の許可と、API GatewayからLambdaを呼び出す許可は別々に必要。
- APIキーはREST APIの使用量管理に使い、認証・認可と混同しない。
AuthorizationのBearerトークンは、対応するオーソライザーなどで検証して初めて認証情報として機能する。 - API Gatewayは負荷に対応してスケールするが、クォータを超えると429を返すことがある。上限値はリージョンやアカウントなどの条件で確認する。
- 429や一時的な5xxへの再試行では指数バックオフとジッターを使う。AWS SDKの再試行機能が任意のHTTP API呼び出しに適用されるとは限らず、POSTの再試行には重複実行への対策も必要。
公式ドキュメント
重要ポイント
- ▸API GatewayはHTTPメソッドやパスに応じてLambdaを呼び出し、Lambdaはリクエストを解析してDynamoDBを操作する
- ▸POSTで項目を作成し、GETでパスパラメータなどからキーを取り出して項目を取得する。処理結果はHTTPステータスとJSON本文で返す
- ▸APIキーはREST APIの使用量プランで呼び出し元を識別するために使い、利用者の認証・認可の代わりにはしない
- ▸API Gatewayは需要に応じて処理能力を拡張するが、アカウントやAPIのスロットリング上限を超えると429 Too Many Requestsを返す
- ▸一時的なスロットリングや障害への再試行集中は指数バックオフとジッターで抑え、書き込みの重複実行は冪等性制御で防ぐ
このトピックの学習を完了しますか?
完了状態はいつでも切り替えられます
同じサービスの関連トピック
Amazon API Gateway に関連するトピックを続けて確認できます。