API Gateway WebSocket with Mock Integration

API Gateway WebSocket with Mock Integration

Takahiro Iwasa
Takahiro Iwasa
3 min read
API Gateway WebSocket Mock Integration

AWS users can quickly build WebSocket servers using API Gateway with mock integration.

Creating AWS Resources

Create a CloudFormation template with the following content.

The key points are the following.

  • The messageId is passed through using $input.path('$.messageId') on line 68. For more information about mapping templates, refer to the official documentation.
  • Integration response keys on line 77 and 84 must be statusCode. The AWS official documentation says “For HTTP and MOCK integrations, it is $integration.response.statuscode”.
  • Specifying response templates on the message route on line 85 through 87, the responses are changed according to the messageId value.
AWSTemplateFormatVersion: 2010-09-09
Description: API Gateway WebSocket with Mock Integration
Resources:
  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

Deploy the CloudFormation stack with the following command.

aws cloudformation deploy \
--template-file template.yaml \
--stack-name api-gateway-websocket-with-mock-integration

To check the values for testing, run the following command.

$ 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"
  }
]

Testing

Install wscat as a WebSocket client.

npm i wscat

Connect to the API Gateway WebSocket endpoint by running the following command. The $connect route is used on new connection.

$ wscat -c wss://<id>.execute-api.<region>.amazonaws.com/production/
Connected (press CTRL+C to quit)

Sending test messages by running the following command. You will see the response changed based on the messageId.

> {"action": "message", "messageId": 1}
< {"message": "Hello World"}
> {"action": "message", "messageId": 2}
< {"message": "Hi!"}

Cleaning Up

Clean up the provisioned AWS resources with the following command.

aws cloudformation delete-stack --stack-name api-gateway-websocket-with-mock-integration

Conclusion

During developing applications connecting to API Gateway WebSocket endpoints, the mock integration can help you implement a client without having to wait for server implementation.

I hope you will find this post useful.

Takahiro Iwasa

Takahiro Iwasa

Software Developer at KAKEHASHI Inc.
Involved in the requirements definition, design, and development of cloud-native applications using AWS. Now, building a new prescription data collection platform at KAKEHASHI Inc. Japan AWS Top Engineers 2020-2023.