0
0
AwsHow-ToBeginner · 4 min read

How to Use WebSocket API in AWS API Gateway

To use WebSocket API in AWS API Gateway, create a WebSocket API with defined routes for connection, messaging, and disconnection events. Deploy the API and connect clients to the WebSocket URL to enable real-time two-way communication.
📐

Syntax

The WebSocket API in API Gateway uses specific route keys to handle different connection events:

  • $connect: Triggered when a client connects.
  • $disconnect: Triggered when a client disconnects.
  • $default: Handles all other messages.

Each route is linked to an integration such as a Lambda function to process the event.

terraform
resource "aws_apigatewayv2_api" "websocket_api" {
  name          = "example-websocket-api"
  protocol_type = "WEBSOCKET"
  route_selection_expression = "$request.body.action"
}

resource "aws_apigatewayv2_integration" "connect_lambda" {
  api_id           = aws_apigatewayv2_api.websocket_api.id
  integration_type = "AWS_PROXY"
  integration_uri  = aws_lambda_function.connect_lambda.arn
  integration_method = "POST"
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_integration" "disconnect_lambda" {
  api_id           = aws_apigatewayv2_api.websocket_api.id
  integration_type = "AWS_PROXY"
  integration_uri  = aws_lambda_function.disconnect_lambda.arn
  integration_method = "POST"
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_integration" "default_lambda" {
  api_id           = aws_apigatewayv2_api.websocket_api.id
  integration_type = "AWS_PROXY"
  integration_uri  = aws_lambda_function.default_lambda.arn
  integration_method = "POST"
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_route" "connect" {
  api_id    = aws_apigatewayv2_api.websocket_api.id
  route_key = "$connect"
  target    = "integrations/${aws_apigatewayv2_integration.connect_lambda.id}"
}

resource "aws_apigatewayv2_route" "disconnect" {
  api_id    = aws_apigatewayv2_api.websocket_api.id
  route_key = "$disconnect"
  target    = "integrations/${aws_apigatewayv2_integration.disconnect_lambda.id}"
}

resource "aws_apigatewayv2_route" "default" {
  api_id    = aws_apigatewayv2_api.websocket_api.id
  route_key = "$default"
  target    = "integrations/${aws_apigatewayv2_integration.default_lambda.id}"
}
💻

Example

This example shows how to create a WebSocket API in AWS API Gateway with Lambda integrations for connect, disconnect, and default routes. It demonstrates setting up the API, routes, and deploying it for client connections.

python
import boto3

apigatewayv2 = boto3.client('apigatewayv2')
lambda_client = boto3.client('lambda')

# Create WebSocket API
response = apigatewayv2.create_api(
    Name='ExampleWebSocketAPI',
    ProtocolType='WEBSOCKET',
    RouteSelectionExpression='$request.body.action'
)
api_id = response['ApiId']

# Create integrations (replace with actual Lambda ARNs)
connect_integration = apigatewayv2.create_integration(
    ApiId=api_id,
    IntegrationType='AWS_PROXY',
    IntegrationUri='arn:aws:lambda:region:account-id:function:connect_lambda',
    IntegrationMethod='POST',
    PayloadFormatVersion='2.0'
)
disconnect_integration = apigatewayv2.create_integration(
    ApiId=api_id,
    IntegrationType='AWS_PROXY',
    IntegrationUri='arn:aws:lambda:region:account-id:function:disconnect_lambda',
    IntegrationMethod='POST',
    PayloadFormatVersion='2.0'
)
default_integration = apigatewayv2.create_integration(
    ApiId=api_id,
    IntegrationType='AWS_PROXY',
    IntegrationUri='arn:aws:lambda:region:account-id:function:default_lambda',
    IntegrationMethod='POST',
    PayloadFormatVersion='2.0'
)

# Create routes
routes = [
    {'route_key': '$connect', 'integration_id': connect_integration['IntegrationId']},
    {'route_key': '$disconnect', 'integration_id': disconnect_integration['IntegrationId']},
    {'route_key': '$default', 'integration_id': default_integration['IntegrationId']}
]

for route in routes:
    apigatewayv2.create_route(
        ApiId=api_id,
        RouteKey=route['route_key'],
        Target=f"integrations/{route['integration_id']}"
    )

# Deploy API
apigatewayv2.create_deployment(ApiId=api_id, Description='Initial deployment')

print(f'WebSocket API created with ID: {api_id}')
Output
WebSocket API created with ID: a1b2c3d4e5
⚠️

Common Pitfalls

  • Not defining the $connect and $disconnect routes causes connection lifecycle events to be ignored.
  • Forgetting to deploy the API after changes means clients connect to outdated configurations.
  • Incorrect route selection expression can prevent messages from routing properly.
  • Not granting Lambda permission to be invoked by API Gateway causes integration failures.
terraform
Wrong example:

resource "aws_apigatewayv2_route" "missing_connect" {
  api_id    = aws_apigatewayv2_api.websocket_api.id
  route_key = "sendMessage"  # Missing $connect route
  target    = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}

Right example:

resource "aws_apigatewayv2_route" "connect" {
  api_id    = aws_apigatewayv2_api.websocket_api.id
  route_key = "$connect"
  target    = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}
📊

Quick Reference

Key points to remember when using WebSocket API in API Gateway:

  • Use $connect, $disconnect, and $default routes.
  • Set routeSelectionExpression to parse client messages.
  • Integrate routes with Lambda or other AWS services.
  • Deploy the API after any configuration changes.
  • Manage client connections using the callbackUrl from the deployed API.

Key Takeaways

Always define $connect, $disconnect, and $default routes for WebSocket lifecycle management.
Deploy your API after changes to make them effective for clients.
Use routeSelectionExpression to route messages based on client payload.
Grant proper permissions for Lambda integrations to be invoked by API Gateway.
Test client connections using the WebSocket URL provided after deployment.