WebSocket API
Resource Overview
A WebSocket API supports bidirectional communication between clients and applications. Unlike traditional HTTP-based request/response models, WebSocket APIs support asynchronous messaging via connections and callbacks and support a push-based workflow for both clients and applications.
This means a client and application can send messages to one another independently, reducing the amount of calls to the backend. Check out these AWS docs to learn more about AWS WebSocket APIs, including how they differ from REST APIs.
Event Subscription
Event subscription wires (solid line) visualize and configure event subscription integrations between two resources.
The following resources can be subscribed to a WebSocket API Authorizer or Route:
- Function
Service Discovery
Service discovery wires (dashed line) provide compute resources (Function, Edge Function) with the permissions and environment variables required to perform actions using cloud resources within the stack. This resource is on the receiving end of a service discovery wire originating from compute resources.
The following compute resources can use a service discovery wire to access a WebSocket API resource:
- Function
- Edge Function
- Docker Task
Configurable Properties
Display Name
Human readable name for this resource that is displayed on the Stackery Dashboard and Stackery CLI output.
Logical ID
The unique identifier used to reference this resource in the stack template. Defining a custom Logical ID is recommended, as it allows you to quickly identify a resource and any associated sub-resources when working with your stack in AWS, or anywhere outside of the Stackery Dashboard. As a project grows, it becomes useful in quickly spotting this resource in template.yaml
or while viewing a stack in Template View mode.
The Logical ID of all sub-resources associated with this WebSocket API will be prefixed with this value.
The identifier you provide must only contain alphanumeric characters (A-Za-z0-9) and be unique within the stack.
Default Logical ID Example: Websocket2
IMPORTANT : AWS uses the Logical ID of each resource to coordinate and apply updates to the stack when deployed. On any update of a resource's logical ID (or any modification that results in one), CloudFormation will delete the currently deployed resource and create a new one in it's place when the updated stack is deployed.
Route Key Selection Expression
The expression that is evaluated by the WebSocket API to determine which route to send any incoming client requests to. If a Route has the Route Key that matches the evaluated result of this expression, the WebSocket API will send it the incoming message.
Default Expression: $request.body.action
Here's an example using the default expression and the following message:
{
"service": "myChatService",
"action": "sendMessage",
"data": {
"roomNum": "12",
"message": "Hello"
}
}
When the WebSocket API receives this client request, the request is evaluated using the Route Key Selection Expresssion. The action key sendMessage
is the evaluated result and is used as the Route Key to identify the target Route. The request is passed to the target route if it exists. If the WebSocket API isn't able to identify a route or the selection expression cannot be evaluated against the request, it will return an error, or send the request to the $default
route if one exists.
WebSocket APIs only accept JSON-formatted messages
Custom Authorizers
In order to control access to a WebSocket API, you can enable IAM Authorization, or create a custom authorizer backed by a Function resource. Update this field to name your custom authorizer.
After providing the name of the custom authorizer and saving the resource configuration, an Authorizer will populate in the WebSocket API resource for you to configure.
IMPORTANT: Only the
$connect
route is able to use a custom authorizer as its Authorization Type. See the Authorizer section below for more details.
Route Key
The value that the WebSocket API uses to determine which route to direct incoming client requests to. After providing the route key, a Route (with the same name) will populate in the WebSocket API resource for you to configure.
Special Route Keys can also be used to define reserved WebSocket API Routes that can manage client connections or provide default routing.
Route
Double-click on the Route to configure the following properties:
Operation Name
The identifier for the operation behind this route.
Send Responses
Enable this property to allow this WebSocket API Route to send response messages back to the client.
Authorization Type
To control access to a WebSocket API, select an authorization type for the $connect
route:
- None: No authorization for the WebSocket API.
- IAM Credentials : Require clients to possess the appropriate IAM credentials to access the WebSocket API.
- Custom Authorizer : The WebSocket API's
$connect
route can use a custom authorizer Function that includes authorization logic unique to your WebSocket API. Select an existing Custom Authorizer you've configured from the next drop-down menu.
Custom Authorizer
If Custom Authorizer
is selected as the Authorization Type, this property will populate and you'll be prompted to choose an existing Custom Authorizer to use.
All Routes in a WebSocket API must be integrated (solid line) with a Function, otherwise, the stack deployment will fail.
Authorizer
Double-click on the Authorizer to configure the following properties:
Result Cache Time-to-Live
This value is time-to-live, in seconds, for cached authorization results returned by the Function handling authorization.
Default TTL: 300s (5 minutes)
Maximum TTL: 3600s (1 hour)
Setting this value to 0 disables connection result caching
Identity Sources
One or more mapping expressions that resolve to authorization parameters. These parameters are used to validate the request and create an authorization caching key. If the request is valid, the Authorizer will invoke its associated Function to perform the custom authorization logic. If the request is invalid, a 401 Unauthorized
response is returned and the associated Function is not invoked.
Required if Result Cache Time-to-Live is enabled (not 0)
Default Expression: route.request.querystring.Auth
A WebSocket API Authorizer must be integrated (solid line) with a Function, otherwise the stack deployment will fail.
IAM Permissions
When connected by a service discovery wire (dashed wire), a compute resource (Function, Edge Function, or Docker Task) will add the following IAM policy to its role and gain permission to access this resource.
- Effect: Allow
Action:
- execute-api:ManageConnections
Resource:
- !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${Websocket}/*
The IAM policy statement above allows the compute resource (Function, Edge Function or Docker Task) to perform the execute-api:ManageConnections
action on the WebSocket API. With this policy statement, the Function or Edge Function is allowed to send messages back to clients that are connected to the WebSocket API.
Environment Variables
When connected by a service discovery wire (dashed wire), a compute resource will automatically populate and reference the following environment variables in order to interact with this resource.
API_URL
Commonly referred to as the WebSocket URL in AWS documentation. Clients use a connection utility like wscat and include this URL to connect and send messages to the WebSocket API.
Example: wss://0ja1ap4mr7.execute-api.us-east-1.amazonaws.com/myEnvironment
API_CONNECTIONS_ENDPOINT
Commonly referred to as the Connection URL in AWS documentation. Backend services include this endpoint in their HTTP requests to send callback messages to a connected client, retrieve connection information, or disconnect the client from the WebSocket API resource.
Example: https://0ja1ap4mr7.execute-api.us-east-1.amazonaws.com/myEnvironment/
Special Route Keys
WebSocket APIs have reserved Route Keys that can be applied to the WebSocket API to manage connections and default routing behavior.
$connect
Executed when the client-websocket connection is being established.
Required for custom authorization
$disconnect
Executed when the client disconnects from the WebSocket API.
$default
Executed when the WebSocket API is not able to match the Route Key in the client request, to an existing Route. If a request provides an invalid route, or if the request is not JSON-formatted, this route will be executed. Useful when defining a "fallback" route or error handling.
Working with a WebSocket API
A deployed WebSocket API will return the following URLs:
- WebSocket URL : Use this URL in a client to establish a connection to the WebSocket API.
- Connection URL : Available documentation also refers to this URL as the Callback URL. Use this URL in the backend to asynchronously send messages to connected clients.
Once a connection is established, a Connection ID is used for bidirectional communication. It's common to manage Connection IDs in a Table (DynamoDB table) in order to maintain current API connections. This is typically done in the Function backing the $connect
and disconnect
routes.
AWS provides an example of an efficient WebSocket API workflow, which can be mirrored and implemented quickly using Stackery.
As mentioned above in Environment Variables, these values will populate automatically as environment variables to access from within an integrated (via service discovery wire) Function. The Function can manage requests and responses between the client and WebSocket API.
Metrics & Logs
Double clicking a resource while viewing the Stack's current deployment, provides access to pre-configured resource properties, and links to the following metrics and logs.
- Connection Metrics
- Message Metrics
- Integration Response Time
Related AWS Documentation
- AWS Documentation: AWS::ApiGatewayV2::Api
- API Reference: Amazon API Gateway V2
- AWS SDK: Node.js | Python | Java | .NET