WebSocket API

API Gateway の WebSocket API でサーバーレスなリアルタイム双方向通信を実現する仕組み

AWSリアルタイム

WebSocket API とは

API Gateway の WebSocket API は、サーバーレスアーキテクチャでリアルタイム双方向通信を実現する仕組みである。チャット、通知、ダッシュボードのリアルタイム更新など、サーバーからクライアントへのプッシュ配信が必要なユースケースで使われる。

通常の REST API はリクエスト/レスポンスの 1 往復で完結するが、WebSocket API は接続を維持し、サーバーとクライアントが任意のタイミングでメッセージを送受信できる。

アーキテクチャ

[クライアント] ←WebSocket→ [API Gateway][Lambda][DynamoDB (接続管理)]

ルート:
  $connect    → ConnectHandler (接続 ID を DynamoDB に保存)
  $disconnect → DisconnectHandler (接続 ID を削除)
  $default    → MessageHandler (メッセージを処理)
  sendMessage → SendHandler (カスタムルート)

接続管理

WebSocket API では、接続中のクライアントを DynamoDB で管理する。

// $connect: 接続時に接続 ID を保存
export const connectHandler = async (event: APIGatewayProxyEvent) => {
  await ddb.send(new PutCommand({
    TableName: 'Connections',
    Item: {
      connectionId: event.requestContext.connectionId,
      connectedAt: new Date().toISOString(),
    },
  }));
  return { statusCode: 200 };
};

// サーバーからクライアントにメッセージを送信
const apigw = new ApiGatewayManagementApiClient({
  endpoint: `https://${domainName}/${stage}`,
});

await apigw.send(new PostToConnectionCommand({
  ConnectionId: connectionId,
  Data: JSON.stringify({ message: 'Hello!' }),
}));

ブロードキャスト (全クライアントに送信)

// DynamoDB から全接続 ID を取得し、それぞれにメッセージを送信
const connections = await ddb.send(new ScanCommand({ TableName: 'Connections' }));

await Promise.allSettled(
  connections.Items!.map(conn =>
    apigw.send(new PostToConnectionCommand({
      ConnectionId: conn.connectionId,
      Data: JSON.stringify({ message: 'Broadcast!' }),
    })).catch(async (err) => {
      if (err.statusCode === 410) {
        // 410 Gone: 接続が切れている → DynamoDB から削除
        await ddb.send(new DeleteCommand({
          TableName: 'Connections',
          Key: { connectionId: conn.connectionId },
        }));
      }
    })
  )
);

SSE との使い分け

観点 WebSocket API SSE (Server-Sent Events)
通信方向 双方向 サーバー → クライアント
AWS 実装 API Gateway WebSocket Lambda Function URL
接続管理 DynamoDB で自前管理 不要
適するケース チャット、ゲーム 通知、ダッシュボード

WebSocket API の関連書籍も参考になる。

関連用語