The API Gateway WebSocket APIs are emulated by Serverless Offline, but setting it right can be tricky.
In production, you probably want to use the Amazon API Gateway Management API SDK client
.
pnpm i @aws-sdk/client-apigatewaymanagementapi
But it won't work properly offline so you need to check if you are offline and send a request instead to the @connections/{connectionId}
local management endpoint.
The IS_OFFLINE
variable is injected by Serverless Offline.
const { WS_ENDPOINT, IS_OFFLINE } = process.env
const client = new ApiGatewayManagementApi({
apiVersion: "2018-11-29",
endpoint: WS_ENDPOINT,
})
const sendToConnection = async (connectionId, input) => {
if (IS_OFFLINE === "true") {
await fetch(`http://127.0.0.1:3001/@connections/${connectionId}`, {
method: "POST",
body: JSON.stringify(input),
})
} else {
await client.postToConnection({
ConnectionId: connectionId,
Data: Buffer.from(JSON.stringify(input)),
})
}
}
To easily get the endpoint you will be making requests in production when you deploy and assign to the environment variables of your Lambda function you can use the following value.
It assumes you are using a serverless.ts
or .js
file and deploying to us-east-1
.
const WS_ENDPOINT = {
"Fn::Join": [
"",
[
"https://",
{
Ref: "WebsocketsApi",
},
`.execute-api.us-east-1.`,
{
Ref: "AWS::URLSuffix",
},
`/${stage}`,
],
],
}
const environment = {
WS_ENDPOINT,
}