As many of you likely remember, AWS finally added support for WebSockets in API Gateway & Lambda at last year's re:Invent. While we were all waiting for CloudFormation support, we created an official Serverless Framework plugin to support WebSockets in the Framework right away.
This was only a temporary measure until CloudFormation support was added. And now, it has been! So we are incredibly excited to announce that the Serverless Framework v1.38 now has support for WebSockets integrated into Framework core. No plugin required.
Note: This means that the serverless-websockets-plugin is officially deprecated. We will no longer maintain it.
Get Started with WebSockets on the Serverless Framework
To start using WebSockets in your serverless projects, subscribe your functions to the new websocket
event by specifying the desired routes that would invoke your function:
functions:
default:
handler: handler.default
events:
- websocket: $default
This will create a $default
route that will forward all WebSocket events (including $connect
and $disconnect
) to your default
function.
You can also specify your event as an object and add more routes:
functions:
connect:
handler: handler.connect
events:
- websocket:
route: $connect
disconnect:
handler: handler.disconnect
events:
- websocket:
route: $disconnect
default:
handler: handler.default
events:
- websocket:
route: $default
echo:
handler: handler.echo
events:
- websocket:
route: $echo
The object notation will be useful when you want to add more configuration to your WebSocket events. For example, when we add support for authorizers in an upcoming release.
Once you deploy this service, you'll see the endpoint of your WebSocket backend in your terminal. Using this endpoint, you can connect to your WebSocket backend using any WebSocket client.
You could also have another function with http
event, so your service would expose two endpoints: one for websockets, the other for http.
Specifying Route Selection Expression
By default, the route selection expression is set to $request.body.action
. This property tells API Gateway how to parse the data coming into your WebSocket endpoint.
So with this default behavior and using the service above, you can invoke the echo
function by using the following JSON object as your websocket event body:
{
"action": "echo",
"data": "hello"
}
You can overwrite the route expression by specifying the websocketsApiRouteSelectionExpression
key in the provider
object:
provider:
name: aws
runtime: nodejs8.10
websocketsApiRouteSelectionExpression: "$request.body.route"
In that case, your WebSocket body should be:
{
"route": "echo",
"data": "hello"
}
Remember that any other body/data coming to your WebSocket backend would invoke the default function.
Communicating with clients
The Framework also takes care of setting the permissions required for your Lambda function to communicate to the connected clients. This means you'll be able to send data to any client right away by using the new ApiGatewayManagementApi
Service, without having to worry about IAM policies:
const client = new AWS.ApiGatewayManagementApi({
apiVersion: '2018-11-29',
endpoint: `https://${event.requestContext.domainName}/${event.requestContext.stage}`
});
await client
.postToConnection({
ConnectionId: event.requestContext.connectionId,
Data: `echo route received: ${event.body}`
})
.promise();
Note: At the time of writing, the Lambda runtime does not include the latest version of the AWS SDK that contains this new ApiGatewayManagementApi
service. So you'll have to deploy your own by adding it to your package.json
.
And that's pretty much all you need to do to get started with WebSockets events! For more information, please check out our docs.
Changelog
Other than WebSockets support, we added a lot of enhancements and bug fixes in this release. Here's our changelog, with some links to the corresponding PRs.
- Set timeout & others on context in python invoke local
- Append in Custom Syntax
- Don't load config for
config
- Replace blocking fs.readFileSync with non blocking fs.readFile in checkForChanges.js
- Added layer option for deploy function update-config
- fix makeDeepVariable replacement
- Make local ruby pry work
- Replace \ with / in paths on windows before passing to nanomatch
- Support deploying GoLang to AWS from Windows!
- Fix windows go rework
- Make use of join operator first argument in sns docs
- add support for command type='container'
- Add Google Python function template
- Update config-credentials.md
- Update bucket conf to default AES256 encryption.
- Fix: override wildcard glob pattern (**) in resolveFilePathsFromPatterns
- Indicate unused context in aws-nodejs-typescipt
- Add stack trace to aws/invokeLocal errors
- Missing underscore
- Updating cloudformation resource reference url
- Docs: Replacing "runtimes" with "templates"
- Add support for websockets event
- AWS: ${ssm} resolve vairbale as JSON if it is stored as JSON in Secrets Manager
- Fix service name in template install message
Roadmap and focus
Over the next few releases, we'll be enhancing WebSockets support with more features, like authorizers and request responses. We're also focusing on improving the local development experience. Keep an eye on the upcoming milestones to stay up to date with what's coming:
Contributor thanks
We had more than 20 contributors have their work go into this release and we can't thank each of them enough. You all make the community special.
Want to have your github avatar and name in the next release post? Check out these issues we are looking for help on!