API Gateway WebSocket: Implementing a Mock Integration
Building an API Gateway WebSocket API entirely with mock integrations, returning canned responses with no backend Lambda involved.
API Gateway’s mock integration can serve canned WebSocket responses without any backend behind it, which is useful for validating routing and response shapes before real business logic exists.
Integrations for WebSocket APIs in API Gateway
Building
- The
messageIdis passed through using$input.path('$.messageId')on line 68. - Integration response keys on lines 77 and 84 must be
statusCode. - Response templates for the
messageroute on lines 85-87 modify responses based on themessageIdvalue.
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.ApiEndpointDeploy the CloudFormation stack with the following command:
aws cloudformation deploy \ --template-file template.yaml \ --stack-name api-gateway-websocket-with-mock-integrationTo get the deployed API Gateway endpoint, use the following command:
aws cloudformation describe-stacks \ --stack-name api-gateway-websocket-with-mock-integration \| jq ".Stacks[0].Outputs"Example Output:
[ { "OutputKey": "ApiGatewayV2ApiEndpoint", "OutputValue": "wss://<id>.execute-api.<region>.amazonaws.com" }]Testing
Install wscat as a WebSocket client:
npm i wscatRun the following command to connect to the WebSocket endpoint. The $connect route is used for new connections.
wscat -c wss://<id>.execute-api.<region>.amazonaws.com/production/Send test messages and observe the responses based on the messageId:
> {"action": "message", "messageId": 1}< {"message": "Hello World"}> {"action": "message", "messageId": 2}< {"message": "Hi!"}Cleaning Up
Clean up all the AWS resources provisioned during this example with the following command:
aws cloudformation delete-stack \ --stack-name api-gateway-websocket-with-mock-integrationConclusion
Building an API Gateway WebSocket API entirely with mock integrations returned different canned responses based on the incoming messageId, with no backend Lambda deployed. Mock integration works here because the “backend” is just static response templates keyed off messageId, which makes it a good fit for prototyping a WebSocket API’s routing and response shape before any real backend exists — no Lambda function or persistent connection handling needs to be written just to validate that $connect and message routes behave as expected. That said, TemplateSelectionExpression only supports the kind of static, value-based branching shown here; anything requiring actual computation, persistence, or a call to another service means swapping the mock integration for a Lambda or HTTP integration, since VTL templates alone can’t express that.
Related posts
Calling SageMaker from API Gateway Without Lambda
Wiring API Gateway's integration request directly to a SageMaker inference endpoint, cutting the Lambda function out of the request path entirely.
Sign in with Slack Using Cognito User Pools and OIDC
Federating Cognito user pools with Slack over OIDC and wiring "Sign in with Slack" into a Next.js app with Amplify.
Deploying FastAPI on AWS Lambda with Lambda Web Adapter
This example guides you through the process of developing API backends with FastAPI using Lambda Web Adapter.
Uploading to S3 Through CloudFront Pre-Signed URLs
CloudFront signed URLs let you upload to S3 through a custom domain—useful when direct S3 pre-signed URLs are not an option.
AWS EventBridge Scheduler: Starting and Stopping EC2 on a Schedule
Starting and stopping EC2 instances on a cron schedule with EventBridge Scheduler calling the EC2 API directly, no Lambda involved.
