Serverless WebSocket route responses

Viewed 1019

I am using serverless to create a WebSocket service, for which I am able to successfully trigger my WebSocket routes locally, using serverless-offline and for the deployed service.

The issue I am having now is responding to those WS events.

I am able to use AWS.ApiGatewayManagementApi.postToConnection to respond to my local WebSocket events, though I cannot seem to get the return value of my handler to actually send a WebSocket event in response, as these serverless-offline docs and these AWS docs suggest.

The serverless.yml route:

  ws-custom:
    handler: handler.wsCustom
    events:
      - websocket:
          route: custom
          routeResponseSelectionExpression: $default

The handler:

module.exports.wsCustom = async (event) => {
  const body = JSON.parse(event.body);
  console.log('WebSocket `custom` event!', event);

  return {
    statusCode: 200,
    body: JSON.stringify({ message: `Hello, ${body.name}!` }),
  };
}

Invoking the function in my browser JavaScript:

ws.send(JSON.stringify({ 'action': 'custom', 'name': 'kevbot' }));

The result is that my serverless-offline logs (or CloudWatch in the case of the deployed project) will create an event with the log successfully, but my client will receive no events in response. Does anyone know how I can do this with the return value of the handler?

EDIT:

The problem seems to exist within my serverless-offline setup. I will attempt to get it working locally and will create an issue necessary.

1 Answers

An important point to note when using WebSocket APIs and trying to return a response from your integration back to the client, as mentioned in this doc:

For a route that is configured to use AWS_PROXY or LAMBDA_PROXY integration, communication is one-way, and API Gateway will not pass the backend response through to the route response automatically. For example, in the case of LAMBDA_PROXY integration, the body that the Lambda function returns will not be returned to the client. If you want the client to receive integration responses, you must define a route response to make two-way communication possible.

So, if you are using a proxy integration, then you cannot return a response back to the client. You would have to use the AWS.ApiGatewayManagementApi.postToConnection method to communicate any data.

Alternatively, if you are using a non-proxy integration, then you can set up a route response for your integration.

Related