AWS - API Gateway
概要
AWS API Gatewayは、AWSが提供するフルマネージド型のAPIサービスである。
開発者がRESTful APIやWebSocket APIを簡単に作成、公開、管理、保護できる環境を提供する。
主な特徴を以下に示す。
- フルマネージド
- サーバ管理やスケーリングの自動化
- 複数のAPIタイプ
- REST API、HTTP API、WebSocket APIをサポート
- バックエンド統合
- Lambda、EC2、DynamoDB、他のAWSサービスとの統合
- セキュリティ機能
- IAM認証、Cognito認証、APIキー、カスタムオーソライザー
- トラフィック管理
- スロットリング、キャッシング、リクエスト検証
- モニタリング
- CloudWatchとの統合による詳細なメトリクス
AWS API Gatewayが提供する3つのAPIタイプを以下に示す。
- REST API
- 従来型のRESTful API、豊富な機能を提供
- API管理機能、リクエスト変換、レスポンス変換をサポート
- HTTP API
- シンプルで低コストなAPI、REST APIのサブセット
- 基本的な機能に特化し、最大70%のコスト削減が可能
- WebSocket API
- 双方向通信をサポート、リアルタイムアプリケーション向け
- チャット、ゲーム、金融取引アプリケーション等に適する
AWS API Gatewayは永続的な無料利用枠を提供しており、個人利用や小規模なアプリケーションであれば無料枠内で運用できることが多い。
認証方法
AWS Lambdaを使用するアプリケーションを開発する場合、認証戦略を考慮する必要がある。
- Cognito認証 (推奨)
- 不特定多数向けのクライアントアプリケーション向け。
- ユーザごとに認証・認可を行う場合に最適である。
- ユーザ登録、ログイン、トークン管理等を自動で処理する。
- 特に、ユーザごとにデータを分離する場合、または、細かいアクセス制御が必要な場合に向いている。
- API Keyによる認証 (最も簡単)
- 不特定多数向けのクライアントアプリケーション向け。
- API Gatewayで発行したAPIキーをクライアントアプリケーションに埋め込む方法である。
- ただし、クライアントアプリケーションからキーを抽出される可能性があるため、使用量の制限や課金が必要ない公開APIに適している。
- IAM認証
- 企業内や信頼できるクライアント向け。
- AWS認証情報を使用するため、不特定多数向けには推奨されない。
API Gatewayの無料枠について
無料枠の内容
- HTTP API
- 月100万回のAPIコールまで無料 (永続的)
- この無料枠は永続的に利用可能である。
- REST API
- 月100万回のAPIコールまで無料 (最初の12ヶ月間)
- 12ヶ月後は課金対象となる
- WebSocket API
- 月100万メッセージまで無料 (最初の12ヶ月間)
- 月75万接続分まで無料 (最初の12ヶ月間)
※注意
- HTTP APIの無料枠のみが永続的である。
- REST APIとWebSocket APIの無料枠は最初の12ヶ月間のみである。
- データ転送料金は別途発生する。
- キャッシングを有効にした場合は追加料金が発生する。
料金体系
無料枠を超えた場合の料金 (東京リージョンの例)
- HTTP API
- APIコール : $1.17 / 100万リクエスト
- REST APIと比較して約70%のコスト削減
- REST API
- APIコール : $4.25 / 100万リクエスト
- キャッシング : $0.020 / 時間 (0.5GBキャッシュの場合)
- WebSocket API
- メッセージ : $1.17 / 100万メッセージ
- 接続時間 : $0.315 / 100万接続分
- データ転送
- アウトバウンド : 最初の10[TB]まで $0.114 / GB
- インバウンド : 無料
API Gatewayの停止
AWS API Gatewayには従来的な意味での停止という概念がない。
Lambda同様、サーバーレスサービスであり、リクエストが来た時のみ課金されるためである。
コストを抑える方法
使用していない場合のコストを抑えるには、以下に示す選択肢がある。
1. ステージの削除
- デプロイされたステージを削除する。
- ステージが存在しなければAPIにアクセスできない。
- API自体は残しておくことができる。
2. APIの削除
- 完全に使用しない場合はAPI自体を削除する。
- 必要に応じて再作成可能である。
- CloudFormationやTerraformでインフラストラクチャをコード化しておくことを推奨する。
3. HTTP APIの使用
- 新規作成の場合は、HTTP APIを優先的に検討する。
- REST APIと比較して最大70%のコスト削減が可能である。
- 必要な機能がHTTP APIでカバーできる場合は、HTTP APIを選択する。
4. キャッシングの無効化
- キャッシング機能は使用していなくても課金される。
- 必要がなければキャッシングを無効化する。
コスト構造について
リクエストがない場合
- API自体の維持費は発生しない (無料)
- キャッシングを有効にしている場合のみ時間課金が発生する
- 基本的にコストは0円またはほぼ0円
リクエストがある場合
- リクエスト数に基づいて課金される。
- 例 : HTTP API、月10万リクエストの場合
- 10万リクエスト = 無料枠内 (100万まで無料)
- コスト : $0
- 例 : REST API、月200万リクエストの場合 (12ヶ月後)
- 200万リクエスト × $4.25 / 100万 = $8.50/月
コストを下げる方法
- HTTP APIの活用
- 新規APIはHTTP APIを優先的に検討する。
- REST APIからHTTP APIへの移行を検討する。
- キャッシングの最適化
- 必要な場合のみキャッシングを有効化する。
- キャッシュサイズを適切に設定する。
- リクエストの削減
- バッチ処理やWebSocketの活用を検討する。
- クライアント側でのキャッシングを実装する。
- リージョンの選択
- データ転送コストを考慮してリージョンを選択する。
完全に無料にするには、HTTP APIを使用し、月100万リクエスト以内に抑えること。
HTTP APIの作成
HTTP APIはREST APIよりもシンプルで低コストである。基本的なAPIであればHTTP APIの使用を推奨する。
マネジメントコンソールでの作成
- API Gatewayコンソールで [APIを作成] を選択する。
- HTTP API の [構築] を選択する。
- 統合を追加する。(オプション)
- Lambda
- Lambda関数を選択
- HTTPエンドポイント
- 既存のエンドポイントを指定
- 後で追加することも可能
- Lambda
- API名を入力する。
- 例 : MyHttpAPI
- [次へ]を選択する。
ルートの設定
- HTTPメソッドを選択する。
- GET、POST、PUT、DELETE、PATCH、ANY 等
- リソースパスを入力する。
- 例 : /users、/items/{id} 等
- 統合ターゲットを選択する。
- 先ほど追加したLambda関数等
- 追加のルートを設定する場合は [ルートを追加] を選択する。
- [次へ]を選択する。
ステージの定義
- ステージ名を入力する。
- 例 : $default (デフォルト)、dev、prod等
- 自動デプロイを有効化する。(推奨)
- 変更が自動的にデプロイされる。
- [次へ]を選択する。
確認と作成
- 設定内容を確認する。
- [作成]を選択する。
作成が完了すると、APIのURLが表示される。
https://{api-id}.execute-api.ap-northeast-1.amazonaws.com/{resource}
HTTP APIではステージ名がURLに含まれない場合がある。($defaultステージの場合)
REST APIの作成
マネジメントコンソールでの作成
- AWSマネジメントコンソールにログインする。
- リージョンを選択する。
- 東京リージョン : ap-northeast-1
- 検索バーに "API Gateway" と入力して選択する。
- [APIを作成]を選択する。
APIタイプの選択
- APIタイプを選択する。
- REST API
- 豊富な機能を持つ従来型のRESTful API
- HTTP API
- シンプルで低コストなAPI (推奨)
- WebSocket API
- 双方向通信が必要な場合
- REST API (Private)
- VPC内からのみアクセス可能なAPI
- REST API
- [構築]を選択する。
REST APIの設定
- プロトコルを選択する。
- REST を選択
- 新しいAPIを作成する。
- 新しいAPI
- 新規にAPIを作成
- サンプルAPIのクローン
- Petstore APIのサンプルを使用
- OpenAPI 3.0からインポート
- 既存のOpenAPI定義をインポート
- 新しいAPI
- API名を入力する。
- 例 : MyRestAPI
- 説明を入力する。(オプション)
- 例 : 個人プロジェクト用のREST API
- エンドポイントタイプを選択する。
- リージョン
- 単一リージョンでの展開 (推奨)
- エッジ最適化
- CloudFrontを使用したグローバル配信
- プライベート
- VPC内からのみアクセス可能
- リージョン
- [APIの作成]を選択する。
リソースとメソッドの作成
- リソースの作成
- [リソースを作成]を選択する。
- リソース名を入力する。
- 例 : users
- リソースパスを確認する。
- 自動的に /users が設定される
- [リソースの作成]を選択する。
- メソッドの作成
- 作成したリソース (例 : /users) を選択する。
- [メソッドを作成]を選択する。
- HTTPメソッドを選択する。
- GET、POST、PUT、DELETE、PATCH等
- 統合タイプを選択する。
- Lambda関数
- Lambda関数と統合 (推奨)
- HTTPエンドポイント
- 既存のHTTPエンドポイントにプロキシ
- Mock
- テスト用のモックレスポンス
- AWSサービス
- DynamoDB、S3等と直接統合
- Lambda関数
- Lambda関数を選択する場合
- Lambda関数名を入力する
- Lambda プロキシ統合を有効化する (推奨)
- [保存]を選択する。
- Lambda関数の実行許可を求められた場合は [OK] を選択する。
APIのデプロイ
- [アクション] - [APIのデプロイ]を選択する。
- デプロイされるステージを選択する。
- [新しいステージ]
- 新しいステージを作成
- 既存のステージ
- 既存のステージにデプロイ
- [新しいステージ]
- ステージ名を入力する。
- 例 : dev、prod、test 等
- ステージの説明を入力する。(オプション)
- [デプロイ]を選択する。
デプロイが完了すると、APIのURLが表示される。
https://{api-id}.execute-api.ap-northeast-1.amazonaws.com/{stage-name}/{resource}
# 例 : https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users
Lambda統合の設定
API GatewayとLambda関数を統合する時の設定について示す。
Lambda プロキシ統合
Lambda プロキシ統合を使用すると、APIリクエストの詳細情報がLambda関数に渡される。
- Lambda関数で受け取るイベントの構造
{
"httpMethod": "GET",
"path": "/users",
"queryStringParameters": {
"id": "123"
},
"headers": {
"Content-Type": "application/json"
},
"body": null,
"isBase64Encoded": false
}
- Lambda関数のレスポンス形式
def lambda_handler(event, context):
# リクエスト情報の取得
http_method = event.get('httpMethod')
path = event.get('path')
query_params = event.get('queryStringParameters', {})
# レスポンスの作成
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*' # CORS対応
},
'body': json.dumps({
'message': 'Success',
'data': {'id': '123', 'name': '山田太郎'}
})
}
CORSの設定
クロスオリジンリクエストを許可するには、CORSを設定する必要がある。
- HTTP APIでのCORS設定
- APIを選択する。
- [CORS]を選択する。
- [設定]を選択する。
- アクセスコントロールの設定を行う。
- Access-Control-Allow-Origin
- 例 : * (すべて許可) または https://example.com
- Access-Control-Allow-Methods
- 例 : GET, POST, PUT, DELETE
- Access-Control-Allow-Headers
- 例 : Content-Type, Authorization
- Access-Control-Max-Age
- 例 : 300 (秒)
- Access-Control-Allow-Origin
- [保存]を選択する。
- REST APIでのCORS設定
- リソースを選択する。
- [アクション] - [CORSの有効化] を選択する。
- 設定を確認する。
- [CORSを有効にして既存のCORSヘッダーを置換] を選択する。
- OPTIONSメソッドが自動的に作成される。
Linux PCからのアクセス設定
AWS CLIのインストール
Lambda編で説明した方法と同じ手順でAWS CLIをインストールする。
方法1 : pip経由 (推奨)
Python3をインストールする。
sudo apt update sudo apt install python3 python3-pip -y
AWS CLIをインストールする。
pip3 install awscli --user
正常にインストールされているかどうかを確認する。
aws --version
方法2 : 公式インストーラ
AWS CLIをダウンロードおよびインストールする。
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install
正常にインストールされているかどうかを確認する。
aws --version
AWS CLIの設定
設定コマンドを実行する。
aws configure
以下に示すものを順番に入力する。
- AWS Access Key ID
- 作成したアクセスキーID
- AWS Secret Access Key
- シークレットアクセスキー
- Default region name
- 例 : ap-northeast-1 (東京リージョン)
- Default output format
- json (推奨)
接続テスト
API一覧を取得する。
aws apigateway get-rest-apis
HTTP APIの一覧を取得する。
aws apigatewayv2 get-apis
特定のAPIの情報を取得する。
aws apigateway get-rest-api --rest-api-id {api-id}
API Gatewayの基本操作 (CLI)
APIの一覧取得
# REST APIの一覧
aws apigateway get-rest-apis
# HTTP APIの一覧
aws apigatewayv2 get-apis
リソースの一覧取得
# REST APIのリソース一覧
aws apigateway get-resources \
--rest-api-id abc123def4
APIのデプロイ
# REST APIのデプロイ
aws apigateway create-deployment \
--rest-api-id abc123def4 \
--stage-name dev \
--description "初回デプロイ"
ステージの作成
# 新しいステージの作成
aws apigateway create-stage \
--rest-api-id abc123def4 \
--stage-name prod \
--deployment-id xyz789
APIのテスト
# curlでAPIをテスト
curl https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users
# POSTリクエストの例
curl -X POST \
https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users \
-H "Content-Type: application/json" \
-d '{"name": "山田太郎", "email": "yamada@example.com"}'
# 認証ヘッダを含むリクエスト
curl https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
ログの確認
# CloudWatch Logsのログストリーム確認
aws logs describe-log-streams \
--log-group-name API-Gateway-Execution-Logs_abc123def4/dev \
--order-by LastEventTime \
--descending
APIの削除
# REST APIの削除
aws apigateway delete-rest-api \
--rest-api-id abc123def4
# HTTP APIの削除
aws apigatewayv2 delete-api \
--api-id xyz789ghi0
Python SDK (boto3) の使用
以下の例では、Pythonを使用してAWS API Gatewayを操作している。
まず、boto3とrequestsをインストールする。
pip3 install boto3 requests --user
# apigateway_example.py
import boto3
import json
# API Gatewayクライアントの作成
apigateway = boto3.client('apigateway', region_name='ap-northeast-1')
# REST APIの一覧取得
def list_rest_apis():
response = apigateway.get_rest_apis()
for api in response['items']:
print(f"API名: {api['name']}")
print(f" ID: {api['id']}")
print(f" 作成日: {api['createdDate']}")
print()
# REST APIの作成
def create_rest_api():
response = apigateway.create_rest_api(
name='MyNewAPI',
description='Python SDKで作成したAPI',
endpointConfiguration={
'types': ['REGIONAL']
}
)
api_id = response['id']
print(f"API作成成功: {api_id}")
return api_id
# リソースの取得
def get_resources(api_id):
response = apigateway.get_resources(
restApiId=api_id
)
return response['items']
# リソースの作成
def create_resource(api_id, parent_id, path_part):
response = apigateway.create_resource(
restApiId=api_id,
parentId=parent_id,
pathPart=path_part
)
resource_id = response['id']
print(f"リソース作成成功: /{path_part} (ID: {resource_id})")
return resource_id
# メソッドの作成
def create_method(api_id, resource_id, http_method, lambda_function_arn):
# メソッドの作成
apigateway.put_method(
restApiId=api_id,
resourceId=resource_id,
httpMethod=http_method,
authorizationType='NONE'
)
# Lambda統合の設定
region = 'ap-northeast-1'
uri = f'arn:aws:apigateway:{region}:lambda:path/2015-03-31/functions/{lambda_function_arn}/invocations'
apigateway.put_integration(
restApiId=api_id,
resourceId=resource_id,
httpMethod=http_method,
type='AWS_PROXY',
integrationHttpMethod='POST',
uri=uri
)
print(f"メソッド作成成功: {http_method}")
# デプロイの作成
def deploy_api(api_id, stage_name):
response = apigateway.create_deployment(
restApiId=api_id,
stageName=stage_name,
description='自動デプロイ'
)
deployment_id = response['id']
print(f"デプロイ成功: {deployment_id}")
print(f"APIエンドポイント: https://{api_id}.execute-api.ap-northeast-1.amazonaws.com/{stage_name}")
# ステージ設定の更新
def update_stage_settings(api_id, stage_name):
# ログ記録を有効化
apigateway.update_stage(
restApiId=api_id,
stageName=stage_name,
patchOperations=[
{
'op': 'replace',
'path': '/*/*/logging/loglevel',
'value': 'INFO'
},
{
'op': 'replace',
'path': '/*/*/logging/dataTrace',
'value': 'true'
},
{
'op': 'replace',
'path': '/*/*/metrics/enabled',
'value': 'true'
}
]
)
print("ステージ設定更新完了")
# APIの削除
def delete_rest_api(api_id):
apigateway.delete_rest_api(
restApiId=api_id
)
print(f"API削除完了: {api_id}")
# メイン処理
if __name__ == '__main__':
list_rest_apis()
# 新しいAPIを作成する場合
# api_id = create_rest_api()
# resources = get_resources(api_id)
# root_id = resources[0]['id'] # ルートリソース
# resource_id = create_resource(api_id, root_id, 'users')
# create_method(api_id, resource_id, 'GET', 'arn:aws:lambda:...')
# deploy_api(api_id, 'dev')
# 実行方法 python3 apigateway_example.py
HTTP APIの操作
HTTP APIは異なるクライアント (apigatewayv2) を使用する。
# http_api_example.py
import boto3
# HTTP API用のクライアント
apigatewayv2 = boto3.client('apigatewayv2', region_name='ap-northeast-1')
# HTTP APIの作成
def create_http_api():
response = apigatewayv2.create_api(
Name='MyHttpAPI',
ProtocolType='HTTP',
Description='HTTP APIの例',
CorsConfiguration={
'AllowOrigins': ['*'],
'AllowMethods': ['GET', 'POST', 'PUT', 'DELETE'],
'AllowHeaders': ['Content-Type', 'Authorization']
}
)
api_id = response['ApiId']
print(f"HTTP API作成成功: {api_id}")
return api_id
# HTTP APIの一覧取得
def list_http_apis():
response = apigatewayv2.get_apis()
for api in response['Items']:
print(f"API名: {api['Name']}")
print(f" ID: {api['ApiId']}")
print(f" エンドポイント: {api['ApiEndpoint']}")
print()
# Lambda統合の作成
def create_integration(api_id, lambda_function_arn):
response = apigatewayv2.create_integration(
ApiId=api_id,
IntegrationType='AWS_PROXY',
IntegrationUri=lambda_function_arn,
PayloadFormatVersion='2.0'
)
integration_id = response['IntegrationId']
print(f"統合作成成功: {integration_id}")
return integration_id
# ルートの作成
def create_route(api_id, integration_id, route_key):
response = apigatewayv2.create_route(
ApiId=api_id,
RouteKey=route_key, # 例: 'GET /users', 'POST /items'
Target=f'integrations/{integration_id}'
)
route_id = response['RouteId']
print(f"ルート作成成功: {route_key}")
return route_id
# ステージの作成
def create_stage(api_id, stage_name):
response = apigatewayv2.create_stage(
ApiId=api_id,
StageName=stage_name,
AutoDeploy=True
)
print(f"ステージ作成成功: {stage_name}")
if __name__ == '__main__':
list_http_apis()
APIへのリクエスト送信
作成したAPIにリクエストを送信する例を以下に示す。
# api_request_example.py
import requests
import json
# APIエンドポイント
API_ENDPOINT = 'https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev'
# GETリクエストの例
def get_users():
url = f'{API_ENDPOINT}/users'
response = requests.get(url)
print(f"ステータスコード: {response.status_code}")
print(f"レスポンス: {response.json()}")
# POSTリクエストの例
def create_user():
url = f'{API_ENDPOINT}/users'
data = {
'name': '山田太郎',
'email': 'yamada@example.com',
'age': 30
}
headers = {
'Content-Type': 'application/json'
}
response = requests.post(url, json=data, headers=headers)
print(f"ステータスコード: {response.status_code}")
print(f"レスポンス: {response.json()}")
# 認証付きリクエストの例
def get_protected_resource(token):
url = f'{API_ENDPOINT}/protected'
headers = {
'Authorization': f'Bearer {token}'
}
response = requests.get(url, headers=headers)
print(f"ステータスコード: {response.status_code}")
print(f"レスポンス: {response.json()}")
if __name__ == '__main__':
get_users()
# create_user()
# get_protected_resource('YOUR_TOKEN_HERE')
セキュリティ
認証と認可
API Gatewayは複数の認証方式をサポートしている。
1. APIキー
最もシンプルな認証方式である。
開発環境やパートナーAPIに適している。
APIキーの作成手順
- API Gatewayコンソールで [APIキー] を選択する。
- [APIキーの作成] を選択する。
- 名前を入力する。
- [保存] を選択する。
- 作成されたAPIキーの値を控えておく。
使用量プランの作成
- [使用量プラン] を選択する。
- [作成] を選択する。
- プラン名を入力する。
- スロットリング設定を行う。
- レート : 秒あたりのリクエスト数
- バースト : 一時的な急増を許容する数
- クォータ設定を行う。
- 1日、1週間、または1ヶ月あたりのリクエスト数上限
- APIステージを関連付ける。
- APIキーを関連付ける。
メソッドでのAPIキー要求の設定
- メソッドを選択する。
- [メソッドリクエスト] を選択する。
- [APIキーの必要性] を true に設定する。
- APIを再デプロイする。
クライアントからの使用方法
curl https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users \
-H "x-api-key: YOUR_API_KEY_HERE"
2. IAM認証
AWS IAMを使用した認証である。AWSサービス間の連携に適している。
メソッドでのIAM認証の設定
- メソッドを選択する。
- [メソッドリクエスト] を選択する。
- [承認] で AWS_IAM を選択する。
- APIを再デプロイする。
Python (boto3) からの署名付きリクエスト
import requests
from requests_aws4auth import AWS4Auth
import boto3
# AWS認証情報の取得
session = boto3.Session()
credentials = session.get_credentials()
# AWS4Auth の作成
auth = AWS4Auth(
credentials.access_key,
credentials.secret_key,
'ap-northeast-1',
'execute-api',
session_token=credentials.token
)
# リクエストの送信
url = 'https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users'
response = requests.get(url, auth=auth)
print(response.json())
※注意
requests_aws4authのインストールが必要である。
pip3 install requests-aws4auth
3. Cognito認証
ユーザ管理が必要なアプリケーションに適している。
Cognitoユーザープールの作成
- Amazon Cognito コンソールで [ユーザープールを作成] を選択する。
- 認証フローを設定する。
- ユーザー名とパスワードの要件を設定する。
- アプリクライアントを作成する。
- ユーザープールIDとアプリクライアントIDを控えておく。
API Gatewayでのオーソライザーの設定
- API Gatewayコンソールで [オーソライザー] を選択する。
- [新しいオーソライザーの作成] を選択する。
- タイプで Cognito を選択する。
- Cognitoユーザープールを選択する。
- トークンソースを入力する。
- 例 : Authorization
- [作成] を選択する。
メソッドでのオーソライザーの適用
- メソッドを選択する。
- [メソッドリクエスト] を選択する。
- [承認] で作成したオーソライザーを選択する。
- APIを再デプロイする。
4. Lambda オーソライザー
カスタム認証ロジックが必要な場合に使用する。
Lambda オーソライザー関数の例
# lambda_authorizer.py
import json
def lambda_handler(event, context):
token = event['authorizationToken']
method_arn = event['methodArn']
# トークンの検証ロジック (例: データベースやキャッシュで確認)
if token == 'valid-token-12345':
# 許可ポリシーを返す
return generate_policy('user', 'Allow', method_arn)
else:
# 拒否ポリシーを返す
return generate_policy('user', 'Deny', method_arn)
def generate_policy(principal_id, effect, resource):
auth_response = {
'principalId': principal_id
}
if effect and resource:
policy_document = {
'Version': '2012-10-17',
'Statement': [
{
'Action': 'execute-api:Invoke',
'Effect': effect,
'Resource': resource
}
]
}
auth_response['policyDocument'] = policy_document
# コンテキスト情報を追加 (オプション)
auth_response['context'] = {
'userId': '12345',
'userName': 'yamada'
}
return auth_response
API Gatewayでの設定
- [オーソライザー] を選択する。
- [新しいオーソライザーの作成] を選択する。
- タイプで Lambda を選択する。
- Lambda関数を選択する。
- トークンソースを入力する。
- 例 : Authorization
- [作成] を選択する。
リソースポリシー
API全体へのアクセスを制御する。特定のIPアドレスやVPCからのアクセスを制限できる。
- IPアドレス制限のポリシー例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:123456789012:abc123def4/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"203.0.113.0/24",
"198.51.100.0/24"
]
}
}
}
]
}
- VPC制限のポリシー例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:123456789012:abc123def4/*",
"Condition": {
"StringEquals": {
"aws:SourceVpc": "vpc-12345678"
}
}
}
]
}
スロットリング
レート制限を設定してAPIを保護する。
ステージレベルでのスロットリング設定
- ステージを選択する。
- [設定] タブを選択する。
- デフォルトメソッドスロットリングを設定する。
- レート : 秒あたりのリクエスト数 (例: 100)
- バースト : 同時リクエスト数 (例: 200)
- [変更の保存] を選択する。
メソッドレベルでのスロットリング設定
- ステージを選択する。
- [設定] タブを選択する。
- メソッドスロットリングを追加する。
- メソッドとスロットリング値を設定する。
- [変更の保存] を選択する。
トラブルシューティング
エラー : "Missing Authentication Token"
- 原因
- URLが間違っている、または、リソースが存在しない。
- 解決方法
- APIのURLを確認する。
- リソースパスが正しいか確認する。
- APIがデプロイされているか確認する。
エラー : "{"message":"Forbidden"}" (403)
- 原因
- 認証に失敗した、または、権限がない。
- 解決方法
- APIキーが正しいか確認する。(APIキー認証の場合)
- x-api-keyヘッダーが含まれているか確認する。
- IAM権限を確認する。(IAM認証の場合)
- オーソライザーの設定を確認する。
- リソースポリシーを確認する。
エラー : "{"message":"Internal server error"}" (500)
- 原因
- バックエンド (Lambda等) でエラーが発生した。
- 解決方法
- Lambda関数のCloudWatch Logsを確認する。
- Lambda関数のエラーハンドリングを確認する。
- 統合タイムアウト設定を確認する。
- Lambda関数の実行ロールを確認する。
エラー : "{"message":"Endpoint request timed out"}" (504)
- 原因
- バックエンドの応答がタイムアウトした。
- 解決方法
- 統合タイムアウトを延長する。(最大29秒)
- Lambda関数のタイムアウトを確認する。
- バックエンド処理を最適化する。
- 長時間処理の場合は非同期処理を検討する。
CORSエラー
- 原因
- CORS設定が不足している、または、間違っている。
- 解決方法
- CORSを有効化する。
- Access-Control-Allow-Originヘッダを確認する。
- Access-Control-Allow-Methodsヘッダを確認する。
- OPTIONSメソッドが存在するか確認する。(REST APIの場合)
- Lambdaレスポンスにヘッダーが含まれているか確認する。
- Lambda関数でのCORS対応例
def lambda_handler(event, context):
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE',
'Access-Control-Allow-Headers': 'Content-Type,Authorization'
},
'body': json.dumps({'message': 'Success'})
}
スロットリングエラー (429)
- 原因
- リクエスト数がスロットリング制限を超えた。
- 解決方法
- スロットリング設定を緩和する。
- クライアント側でリトライロジックを実装する。(Exponential Backoff)
- 使用量プランを見直す。
- HTTP APIの使用を検討する。(より高いデフォルト制限)
ログの有効化
トラブルシューティングのため、CloudWatch Logsを有効化することを推奨する。
REST APIのログ有効化
- ステージを選択する。
- [ログ/トレース] タブを選択する。
- CloudWatch設定を有効化する。
- CloudWatch Logs
- チェックを入れる
- ログレベル
- INFO または ERROR
- 完全なリクエスト/レスポンスデータのログ記録
- 必要に応じてチェック (注意: 機密情報が含まれる可能性)
- CloudWatch Logs
- IAMロールを設定する。
- API Gatewayがログを書き込むためのロールが必要
- [変更の保存] を選択する。
HTTP APIのログ有効化
- ステージを選択する。
- [ログとトレース] を選択する。
- アクセスログを有効化する。
- CloudWatch Logsのロググループを指定する。
- ログ形式を選択する。
- CLF、JSON、XML、CSV等
- [保存] を選択する。
X-Rayトレーシング
リクエストの詳細な追跡とパフォーマンス分析にはX-Rayを使用する。
- ステージを選択する。
- [ログ/トレース] タブを選択する。
- X-Ray トレーシングを有効化する。
- [変更の保存] を選択する。
X-Rayコンソールでトレースを確認できる。