Amazon Web Services ブログ

AWS AppSync Events の発表: サーバーレス WebSocket API で、あらゆる規模の Web およびモバイルのリアルタイムエクスペリエンスを実現

2024 年 10 月 30 日、AWS AppSync に AWS AppSync Events の機能が追加されました。この機能を使うと、開発者は安全で高性能なサーバーレス WebSocket API を使って、リアルタイムのイベントデータを数人または数百万人のサブスクライバーに簡単にブロードキャストできます。AWS AppSync Events を使えば、開発者はもう WebSocket インフラストラクチャの構築、コネクション状態の管理、ファンアウトの実装を心配する必要がありません。開発者は単に API を作成し、WebSocket 接続が行われているクライアントにサブスクライブされるイベントをパブリッシュするだけです。 AWS AppSync Event API はサーバーレスなので、すぐに始められ、自動的にスケーリングされ、利用した分だけ支払えばよいというメリットがあります。このブログでは、AWS AppSync Events および、AWS AppSync Event API とは何かを説明し、開発者がどのように始められるかを説明します。

リアルタイムのイベント更新は現在のアプリの重要な機能であり、ユーザーに差別化された経験を提供します。ライブスポーツのスコア、グループチャットメッセージ、価格レベル、または位置情報の更新など、開発者は最新の情報をリアルタイムに提供するアプリを構築したいと考えています。しかし、この機能を実装するのは簡単ではなく、スケーリングが難しくなります。これが AWS AppSync Events によって変わります。AWS AppSync Event API は簡単に設定でき、開発者はすぐに作業を開始し、標準の Web API を使用して WebSocket エンドポイントに接続できます。AWS AppSync Event API はサーバーレスで、接続されている数百万のクライアントにリアルタイムの更新をパブリッシュできるようスケールします。イベントドリブンアーキテクチャに投資してきた組織向けに、AWS AppSync Events は HTTP エンドポイントによるパブリッシュをサポートしています。これにより、Amazon EventBridge などの一般的なサービスとの統合が簡単になり、バックエンドから生成されたイベントを Web およびモバイルアプリに簡単にパブリッシュできます。

AWS AppSync Events では、最初に API を作成し、どの認証モードがサポートされているかなどの基本的な設定を定義します。次に、名前空間に名前を割り当てることによりチャネル名前空間を作成します。これは、その名前空間内のすべてのチャネルの接頭辞にもなります。チャネル名前空間は、そのチャネルの機能を定義します。
たとえば、名前が messages のチャネル名前空間では、 /messages で始まるチャネルを公開およびサブスクライブできます。名前空間内のチャネルは一時的なものであり、必要に応じて作成されます。たとえば、必要に応じて /messages/group/admin または /messages/user/JohnDoe にイベントを公開できます。特定のチャネル /messages/user/JohnDoe のイベントをサブスクライブすることも、チャネルパスの最後にワイルドカードを使用して /messages/* または /messages/user/* のようなサブセットをサブスクライブすることもできます。

コンソールを使ってはじめる

始めるには、AWS AppSync Console にアクセスしてください。そこで [Create API (API を作成)] を選択し、[Event API] を選んでください。API に名前を付け、[Create (作成)] を選択します。数秒で API が作成され、使用できる状態になります。コンソールでは、サービスがイベント API、デフォルトの名前空間、API キーを作成します。同じ結果を AWS CLI、AWS SDK、AWS CloudFormation、AWS CDK でも実現できます。

次に、Pub/Sub エディタに移動します。このエディタでは、コンソールから直接公開とサブスクライブを簡単に行えます。アイデアをすばやくテストし、機能を確認するのに最適なツールです。エディタを使用して、HTTP 経由でイベントを公開し、WebSocket 接続でサブスクリプションを設定できます。イベントを受信するには、[Subscribe] セクションで [Connect]、次に [Subscribe] を選択します。あとはチャネルに公開されたイベントを受信できる状態になります。HTTP エンドポイントでは、最大 5 件のイベントをまとめて公開できます。コンソールから公開するには、JSON オブジェクトの配列を入力するだけです。

例えば、Publish セクションに以下の値を入力してください。

[
  { "message": "hello world!" },
  "New WebSocket API!",
  true,
  100,
  ["L", "G", "T", "M"]
]

5 イベントを Subscribe セクションで受信しました!

アプリケーションとの統合

AWS AppSync Events を使用するアプリケーションを構築するのは簡単です。AppSync Events 用の AWS Amplify クライアントを使用でき、API の構成情報はコンソールの Integrations (統合) タブにあります。

Web ブラウザから API に接続するための外部依存関係はありません。以下の JavaScript のコード例は、ブラウザの Web API WebSocket を使ってエンドポイントに接続する方法を示しています。このコードを使用するには、Event API Settings (設定) ページから HTTP および リアルタイム DNS 名を取得し、API キーをコピーします。次に、ページの開発者コンソールを開きます。スニペットの値を指定し、スニペットを開発者コンソールのエディタに貼り付け、コードを実行します。

const REALTIME_DOMAIN = ''
const HTTP_DOMAIN = ''
const API_KEY = ''

const authorization = { 'x-api-key': API_KEY, host: HTTP_DOMAIN }

function getAuthProtocol() {
  const header = btoa(JSON.stringify(authorization))
    .replace(/\+/g, '-') // Convert '+' to '-'
    .replace(/\//g, '_') // Convert '/' to '_'
    .replace(/=+$/, '') // Remove padding `=`
  return `header-${header}`
}

const socket = await new Promise((resolve, reject) => {
  const socket = new WebSocket(
    `wss://${REALTIME_DOMAIN}/event/realtime`,
    ['aws-appsync-event-ws', getAuthProtocol()])
  socket.onopen = () => {
    socket.send(JSON.stringify({ type: 'connection_init' }))
    resolve(socket)
  }
  socket.onclose = (evt) => reject(new Error(evt.reason))
  socket.onmessage = (event) => console.log('=>', JSON.parse(event.data))
})

socket.send(JSON.stringify({
  type: 'subscribe',
  id: crypto.randomUUID(),
  channel: '/default/*',
  authorization
}))

ブラウザの Web API  fetch メソッドを使用してイベントを送信できます。
たとえば、開発者コンソールで次のように実行します。

const event = {
  "channel": "/default/introductions",
  "events": [
    JSON.stringify({message:'Hello World! Introducing AWS AppSync Events!'})
  ]
}

const response = await fetch(`https://${HTTP_DOMAIN}/event`, {
  method: 'POST',
  headers: authorization,
  body: JSON.stringify(event)
})

console.log(response)

接続、承認、WebSocket の使用についてより詳しく知るには、ドキュメントを参照してください。

イベントハンドラの操作

AWS AppSync Events を使用すると、発行したイベントが処理されたときや、クライアントがチャネルをサブスクライブしようとしたときにビジネスロジックを定義できます。これは、チャネル名前空間内に定義された関数であるイベントハンドラーで行われます。イベントハンドラーはオプションであり、チャネル名前空間の範囲内にあります。AWS AppSync Events は onPublish ハンドラと onSubscribe ハンドラの 2 種類のハンドラをサポートしています。onPublish ハンドラーは、イベントが受信されたときに呼び出され、接続されているクライアントにイベントがブロードキャストされる前に実行されます。onPublish ハンドラから、イベントペイロードの形状を変換したり、イベントをフィルタリングしたり、発行されたイベントを拒否したりできます。ハンドラーは APPSYNC_JS ランタイムで実行されるため、JavaScript を記述するだけです。たとえば、イベントを変換するには、map をイベント配列に適用し、イベントの id とイベントの payload を返すようにします。

export function onPublish(ctx) {
  return ctx.events.map(event => ({
    id: event.id,
    payload: {
      ...event.payload,
      message: event.payload.message.toUpperCase()
    }
  }))
}

特定のイベントを除外し、サブスクライブしているクライアントにブロードキャストされないようにするためには、リストからフィルタリングし、ブロードキャストしたい部分だけを返します。たとえば、イベントの配列に対して filter を呼び出すことができます。

勝率が 90 % を超えるゲームのイベントのみをブロードキャストしたい場合を想像してみましょう。

export function onPublish(ctx) {
  return ctx.events.filter(event => event.payload.odds > 0.9)
}

フィルタリングを使えば、イベントをサイレントに破棄できますが、イベントを破棄するときにパブリッシャーにエラーを返すこともできます。
たとえば、イベントに必ず挨拶メッセージが含まれるようにして、パブリッシャーにエラーを返す場合は以下のようになります。

export function onPublish(ctx) {
  return ctx.events.map(event => {
    if (!event.payload.message) {
      return {
        ...event,
        error: 'You should always included a greeting.'
      }
    }
    return event
  })
}

クライアントがサブスクリプションを確立しようとするときに、onSubscribe ハンドラが呼び出されます。util.unauthorized() を呼び出すことでサブスクリプションを拒否できます。Amazon Cognito User Pools で認証されたユーザーを自分のチャネルのみに制限したい場合は以下のようになります。

export function onSubscribe(ctx) {
  if (ctx.info.channel.path !== `/messages/inbox/${ctx.identity.username}`) {
    console.error(`user ${ctx.identity.username} tried connecting to wrong channel: ${ctx.info.channel.path}`)
    util.unauthorized()
  }
}

クライアントは、パターン /messages/inbox/<username> に一致するチャネルにのみサブスクライブできるようになりました。

イベントドリブンアーキテクチャ

AWS AppSync Events は、イベントドリブンアーキテクチャパターンにシームレスに組み込むことができます。Amazon EventBridge を使えば、API の送信先を設定して、イベントを AWS AppSync Events の HTTPS エンドポイントに転送できます。

EventBridge コンソールで、新しい接続を作成し、認証タイプは [API Key]を選択します。API キー名には x-api-key と入力し、Value にはあなたの API キーの値を入力します。次に、新しい API destination を作成します。API destination endpoint には https://<HTTP_DOMAIN>/event という形式を使用します。ここで <HTTP_DOMAIN> は、前に控えた HTTP ドメインです。HTTP メソッドPOST に設定します。Connctions type は、新しく作成した接続を選択し、を作成します。これで、この宛先をターゲットに設定したルールを作成できます。ターゲットの入力パス (InputPath) には "$.detail" を指定すれば、イベントの詳細全体が Event API に転送されます。

AWS AppSync Events にイベントを転送できるようになりました。たとえば、次の イベントの詳細を使用して EventBridge に発行できます。

{
  "channel": "/default/introductions",
  "events": [
    "{\"message\":\"Hello from EventBridge!\"}"
  ]
}

API の機能の探索

API に複数の認証モードを設定し、それぞれのチャネル名前空間で異なる認証動作を設定することができます。API にカスタムドメインを関連付けて、さらなる保護のために AWS Web Application Firewall を付加できます。また、Amazon CloudWatch メトリクス および Amazon CloudWatch Logs との統合もサポートされているため、API のパフォーマンスを完全に把握できます。

今後の展開

このブログでは、AWS AppSync Events を紹介し、AWS AppSync Event API を始める方法を説明しました。チャネル名前空間、チャネル、ハンドラ、Amazon EventBridge との統合方法についても説明しました。

AWS AppSync Events のリリースは重要なマイルストーンとなりますが、これはスタートに過ぎません。間もなく、双方向の WebSocket とデータソースのサポートを追加する予定です。これにより、カスタムデータソースと送信先を作成でき、Amazon DynamoDB や Amazon Aurora などのデータソースを使用してイベントを拡張または永続化できるようになります。ハンドラーの代替として AWS Lambda 関数のサポートも予定しています。また、型の形状を簡単に共有および適用できるようにするため、スキーマのバリデーションをサポートする予定です。乞うご期待ください。

まとめ

AWS AppSync Events は、AWS AppSync が利用可能なすべてのリージョンで利用できるようになりました。最初のイベント API を作成するには、AWS AppSync コンソールにアクセスしてください。AWS AppSync Events はサーバーレスで、AWS AppSync Event API 操作と実際のリアルタイム接続時間に対してのみ料金が発生します。毎月 25 万回の無料のリアルタイム Event API 操作をご利用いただけます。AWS AppSync Events の詳細については、ドキュメントをご覧ください。価格に関する詳細は、価格ページをご確認ください。

AWS AppSync を使えば、アプリケーションをイベント、データ、AI モデルに簡単に接続できます。AWS AppSync Events を利用すれば、任意のイベントソースから発行された更新を、サーバーレス WebSockets 経由でサブスクライブしているクライアントに送信し、リアルタイムの体験を実現できます。また、AWS AppSync GraphQL では、単一の GraphQL API エンドポイントを使って、アプリケーションを複数のデータベース、マイクロサービス、AI モデルに接続できます。

本記事は「Announcing AWS AppSync Events: serverless WebSocket APIs to power real-time web and mobile experiences at any scale」を翻訳したものです。

翻訳者について

Photo of author

稲田 大陸

AWS Japan で働く筋トレが趣味のソリューションアーキテクト。普段は製造業のお客様を中心に技術支援を行っています。好きな AWS サービスは Amazon Location Service と AWS Amplify で、日本のお客様向けに Amazon Location Service の解説ブログなどを執筆しています。