I am using AWS Cloud Formation and struggling to understand how API Gateway works for Websocket.
I'm looking to get the $connect route responding with the OK and the connection ID assigned by AWS API Gateway.
So for example when doing
wscat -c wss://my-custom-api-gateway-ws.com
I would expect to get
Connected (press CTRL+C to quit)
and a message such as
< {"message": "Connected". "connectionId": "foo"}
or similar. But I keep getting a
wscat -c wss://my-custom-api-gateway-ws.com
error: Unexpected server response: 500
This is what I've tried
wsApiGateway:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: !Sub ${prefix}-ws-gateway
Description: Api Gateway for Websockets
ProtocolType: WEBSOCKET
RouteSelectionExpression: $request.body.action
DisableExecuteApiEndpoint: true
wsConnectRoute:
Type: AWS::ApiGatewayV2::Route
DependsOn:
- wsConnectIntegration
Properties:
ApiId: !Ref wsApiGateway
RouteKey: $connect
AuthorizationType: NONE
OperationName: ConnectRoute
RouteResponseSelectionExpression: $default
Target: !Join
- /
- - integrations
- !Ref wsConnectIntegration
wsConnectIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref wsApiGateway
Description: Websocket $connect integration
IntegrationType: MOCK
RequestTemplates:
application/json: "{\"statusCode\": 200, \"connectionId\": \"$context.connectionId\", \"message\": \"Success\"}"
PayloadFormatVersion: 1.0
wsApiStage:
Type: AWS::ApiGatewayV2::Stage
DependsOn:
- wsConnectRoute
Properties:
StageName: production
Description: Autodeploy in production
AutoDeploy: true
ApiId: !Ref wsApiGateway
AccessLogSettings:
DestinationArn: !GetAtt wsApiGatewayLogGroup.Arn
Format: '{"requestTime":"$context.requestTime","requestId":"$context.requestId","connectionId":"$context.connectionId","domainName":"$context.domainName","stage":"$context.stage","httpMethod":"$context.httpMethod","path":"$context.path","routeKey":"$context.routeKey","status":$context.status,"responseLatency":$context.responseLatency, "responseLength":$context.responseLength, "integrationError":$context.integration.error}'
If I remove the route $connect completely, I can connect but it does not return any message
wscat -c wss://my-custom-api-gateway-ws.com
Connected (press CTRL+C to quit)
And if I send anything through the websocket I am getting an automated response error that contains the connection Id (which I could use as workaround). But I want to get that connection Id when connecting, not when forcing an error.
wscat -c wss://my-custom-api-gateway-ws.com
Connected (press CTRL+C to quit)
> this is a silly message
< {"message": "Forbidden", "connectionId":"H-SaJeT8oECIUg=", "requestId":"H-SbUEHSoEF3JQ="}
My understanding is that I should be able to have it working with MOCK integration type, since I don't need an integration http service or similar and the API Gateway should have all what's needed to respond.
Has anyone achieved something similar?
UPDATE 1 I've manually (no cloud formation yet) followed steps on Setup a basic WebSocket mock in AWS ApiGateway to add a $connect route, with MOCK integration, a response template of
{"statusCode" : 200, "connectionId" : "$context.connectionId"}
but I can't see that connectionId when connecting.
wscat -c wss://foo.execute-api.eu-west-1.amazonaws.com/production
Connected (press CTRL+C to quit)
If, additionally, I add a $default route, then once connected I can send messages to websocket and receive the expected connectionId, but I don't seem to find a way to receive the connectionId only with a $connect route without any additional routes.