API Gateway WebSocket:モック統合の実装
バックエンドのLambdaを一切使わず、モック統合のみでAPI Gateway WebSocket APIを構築し、あらかじめ用意されたレスポンスを返します。
API Gatewayのモック統合を使えば、背後にバックエンドを一切置かずに、あらかじめ用意されたWebSocketレスポンスを返すことができます。これは、実際のビジネスロジックが完成する前にルーティングやレスポンスの形を検証するのに便利です。
Integrations for WebSocket APIs in API Gateway
構築
- 68行目の
$input.path('$.messageId')によってmessageIdが引き渡されます。 - 77行目と84行目にある統合レスポンスのキーは
statusCodeである必要があります。 - 85〜87行目にある
messageルートのレスポンステンプレートは、messageIdの値に応じてレスポンスを変更します。
AWSTemplateFormatVersion: 2010-09-09Description: API Gateway WebSocket with Mock IntegrationResources: ApiGatewayV2Api: Type: AWS::ApiGatewayV2::Api Properties: Name: api-gateway-websocket-with-mock-integration ProtocolType: WEBSOCKET RouteSelectionExpression: $request.body.action
ApiGatewayV2Stage: Type: AWS::ApiGatewayV2::Stage Properties: StageName: production ApiId: !Ref ApiGatewayV2Api AutoDeploy: true
ApiGatewayV2RouteOnConnect: Type: AWS::ApiGatewayV2::Route Properties: ApiId: !Ref ApiGatewayV2Api RouteKey: $connect RouteResponseSelectionExpression: $default Target: !Sub integrations/${ApiGatewayV2IntegrationOnConnect}
ApiGatewayV2RouteOnMessage: Type: AWS::ApiGatewayV2::Route Properties: ApiId: !Ref ApiGatewayV2Api RouteKey: message RouteResponseSelectionExpression: $default Target: !Sub integrations/${ApiGatewayV2IntegrationOnMessage}
ApiGatewayV2RouteResponseOnConnect: Type: AWS::ApiGatewayV2::RouteResponse Properties: ApiId: !Ref ApiGatewayV2Api RouteResponseKey: $default RouteId: !Ref ApiGatewayV2RouteOnConnect
ApiGatewayV2RouteResponseOnMessage: Type: AWS::ApiGatewayV2::RouteResponse Properties: ApiId: !Ref ApiGatewayV2Api RouteResponseKey: $default RouteId: !Ref ApiGatewayV2RouteOnMessage
ApiGatewayV2IntegrationOnConnect: Type: AWS::ApiGatewayV2::Integration Properties: ApiId: !Ref ApiGatewayV2Api ConnectionType: INTERNET IntegrationType: MOCK PassthroughBehavior: WHEN_NO_MATCH RequestTemplates: '$default': '{"statusCode": 200}' TimeoutInMillis: 29000 PayloadFormatVersion: '1.0'
ApiGatewayV2IntegrationOnMessage: Type: AWS::ApiGatewayV2::Integration Properties: ApiId: !Ref ApiGatewayV2Api ConnectionType: INTERNET IntegrationType: MOCK PassthroughBehavior: WHEN_NO_MATCH RequestTemplates: '$default': '{"statusCode": 200, "messageId": $input.path(''$.messageId'')}' TimeoutInMillis: 29000 PayloadFormatVersion: '1.0'
ApiGatewayV2IntegrationResponseOnConnect: Type: AWS::ApiGatewayV2::IntegrationResponse Properties: ApiId: !Ref ApiGatewayV2Api IntegrationId: !Ref ApiGatewayV2IntegrationOnConnect IntegrationResponseKey: /200/
ApiGatewayV2IntegrationResponseOnMessage: Type: AWS::ApiGatewayV2::IntegrationResponse Properties: ApiId: !Ref ApiGatewayV2Api IntegrationId: !Ref ApiGatewayV2IntegrationOnMessage IntegrationResponseKey: /200/ ResponseTemplates: '1': '{"message": "Hello World"}' '2': '{"message": "Hi!"}' TemplateSelectionExpression: ${request.body.messageId}
Outputs: ApiGatewayV2ApiEndpoint: Value: !GetAtt ApiGatewayV2Api.ApiEndpoint次のコマンドでCloudFormationスタックをデプロイします。
aws cloudformation deploy \ --template-file template.yaml \ --stack-name api-gateway-websocket-with-mock-integrationデプロイされたAPI Gatewayのエンドポイントを取得するには、次のコマンドを使用します。
aws cloudformation describe-stacks \ --stack-name api-gateway-websocket-with-mock-integration \| jq ".Stacks[0].Outputs"出力例:
[ { "OutputKey": "ApiGatewayV2ApiEndpoint", "OutputValue": "wss://<id>.execute-api.<region>.amazonaws.com" }]テスト
WebSocketクライアントとしてwscatをインストールします。
npm i wscat次のコマンドを実行してWebSocketエンドポイントに接続します。新規接続には$connectルートが使用されます。
wscat -c wss://<id>.execute-api.<region>.amazonaws.com/production/テストメッセージを送信し、messageIdに応じたレスポンスを確認します。
> {"action": "message", "messageId": 1}< {"message": "Hello World"}> {"action": "message", "messageId": 2}< {"message": "Hi!"}クリーンアップ
次のコマンドで、この例でプロビジョニングしたすべてのAWSリソースをクリーンアップします。
aws cloudformation delete-stack \ --stack-name api-gateway-websocket-with-mock-integrationまとめ
モック統合だけでAPI Gateway WebSocket APIを構築したところ、バックエンドのLambdaを一切デプロイすることなく、受信したmessageIdに応じて異なるあらかじめ用意されたレスポンスが返ってきました。ここでモック統合が機能するのは、「バックエンド」がmessageIdをキーにした単なる静的なレスポンステンプレートに過ぎないからです。これは、実際のバックエンドが存在する前にWebSocket APIのルーティングとレスポンス形状をプロトタイピングするのに適しています。$connectルートとmessageルートが期待通りに動作するかを検証するためだけに、Lambda関数や永続的な接続処理を書く必要はありません。とはいえ、TemplateSelectionExpressionがサポートするのはここで示したような静的な値ベースの分岐だけです。実際の計算や永続化、他のサービスの呼び出しが必要になる場合は、VTLテンプレートだけではそれを表現できないため、モック統合をLambda統合やHTTP統合に置き換える必要があります。
Related posts
LambdaなしでAPI GatewayからSageMakerを呼び出す
API Gatewayの統合リクエストをSageMaker推論エンドポイントに直接接続し、リクエストパスからLambda関数を完全に排除する。
Cognito User PoolsとOIDCでSlackサインインを実装する
Cognito user poolをOIDC経由でSlackと連携させ、"Sign in with Slack"をAmplifyでNext.jsアプリに組み込みます。
Lambda Web AdapterでFastAPIをAWS Lambdaにデプロイする
Lambda Web Adapterを使うと、FastAPIで書いたAPIバックエンドをコンテナのまま単一のLambda関数にデプロイできます。
CloudFront署名付きURL経由でS3にアップロードする
CloudFrontの署名付きURLを使えば、独自ドメイン経由でS3にアップロードできます。S3の直接の署名付きURLが使えない場合に有用です。
AWS EventBridge Scheduler:スケジュールに沿ってEC2を起動・停止する
Lambdaを介さずEventBridge SchedulerがEC2 APIを直接呼び出すことで、cronスケジュールに従ってEC2インスタンスを起動・停止します。
