Amazon Web Services ブログ

AWS AppSync Events との連携: Pub/Sub のためのサーバレス WebSocket

本記事は、2024 年 11 月 25 日に公開された Working with AWS AppSync Events: Serverless WebSockets for Pub/Sub を翻訳したものです。

AWS AppSync は、アプリケーションをイベント、データ、AI モデルに接続することを簡素化し、管理します。新しく追加された AWS AppSync Events により、開発者はサーバーレス WebSocket 経由で、それらのサブスクライブしたクライアントに対して任意のイベントソースからの更新を配信することで、リアルタイムの体験を作成できます。AWS AppSync Events は、GraphQL に縛られないスタンドアロンな Pub/Sub サービスを提供します。

この記事では、リーダーボードというシンプルで実用的なユースケースから始めます。ただし、今後の記事では、様々な認証方式、データの拡張、イベント API が役立つその他のシナリオについても紹介していきます。

アプリケーションの概要

一時リーダーボードは、その名の通り、データを永続化しないリーダーボードです。これは短時間で終了するゲームでよく使われますが、過去に何が言われたかよりも、その瞬間に何が言われたかが重要な、大量のメッセージの行き来するチャットアプリでもこのアーキテクチャは当てはまります。

このソリューションを自分で実装したい場合は、コードと導入手順をこのリポジトリからクローンできます。

以下のスクリーンショットに示されているように、このアプリケーションは単一のページから、ユーザーがリアルタイムですべてのプレーヤーの位置情報の更新をサブスクライブすることができるようになっています。外部ソースからイベントが投稿されるのをシミュレートするため、「シミュレートスコアリング」ボタンが含まれており、「シミュレートスコアリング」ボタンをクリックすると一定の間隔で一連の更新が配信されます。

screenshot of leaderboard web app

アーキテクチャがシンプルであることが重要なポイントです。認可サービス、API、データベースは必要ありません。ウェブアプリケーション内で直接イベント API を利用しているだけなのです。

フルスタックアプリケーションの作成

AWS コンソールでこれを設定する方法が最も簡単ですが、この記事では AWS CDK の L1 コンストラクタを使用して Event API を作成する方法を示します。

さらに、AWS 上でフルスタックアプリケーションを構築する際、AWS Amplify Gen 2 は TypeScript ファーストな開発環境を提供することで優れており、必要に応じて CDK L2 および L1 の構成要素に移行することができます。

AWS Amplify は Publish/Subscribe の簡素化のために使用されますが、イベント API を使うには必須ではありません。

Amplify Gen 2 でフロントエンドリポジトリを初期化するには、次のコマンドを実行してください。

npm create amplify
Bash

そのコマンドは、AWS CDK と Amplify JavaScript ライブラリを自動的にインストールするだけでなく、開発者が AWS バックエンドを追加/変更できる amplify ディレクトリも生成します。

次に、authフォルダとdataフォルダを削除しても構いません。これらは、このプロジェクトでは必要とされない Amazon Cognito と AWS AppSync GraphQL の設定を参照しています。

最後に、amplify/backend.tsを更新して、不要なサービスの記述を削除します。

import { defineBackend } from '@aws-amplify/backend'

const backend = defineBackend({})
TypeScript

AWS CDK を使用したイベント API の作成

AWS Amplify を使って、フルスタック CDK プロジェクトを作成しています。Amplify は複数の AWS サービスを抽象化していますが、AWS が提供するサービスの幅が広いため、CDK コンストラクタを利用してフォールバックするサービスも多数あります。これにより、開発者はこれらのコンストラクタが追加されるとすぐに、コード内で AWS サービスを使い始めることができます。

この機能を活用するため、AWS AppSync の API を作成するために使用される L1 コンストラクトをインポートします。

はじめに、アプリケーションを構成する最小単位の要素をすべて含む個別のリソーススタックを作成します。amplify/backend.ts ファイルに、次の行のコードを追加してください。

const customResources = backend.createStack('custom-resources-leaderboard')
TypeScript

これは単にサービスをグループ化するために使用できる論理的なコンテナです。

本ガイドの目的に沿ったイベント API は、3 つの部分に分かれています。

  1. API そのもの
  2. API が発行とサブスクリプションに使用できる名前空間
  3. API を保護するために必要な認証メカニズム
import {
    AuthorizationType,
    CfnApi,
    CfnApiKey,
    CfnChannelNamespace,
} from 'aws-cdk-lib/aws-appsync'

// previous code...

// new code 
const cfnEventAPI = new CfnApi(customResources, 'cfnEventAPI', {
    name: 'realtime-leaderboard',
    eventConfig: {
        authProviders: [{ authType: AuthorizationType.API_KEY }],
        connectionAuthModes: [{ authType: AuthorizationType.API_KEY }],
        defaultPublishAuthModes: [{ authType: AuthorizationType.API_KEY }],
        defaultSubscribeAuthModes: [{ authType: AuthorizationType.API_KEY }],
    },
})

new CfnChannelNamespace(customResources, 'cfnEventAPINamespace', {
    name: 'default',
    apiId: cfnEventAPI.attrApiId,
})

const cfnApiKey = new CfnApiKey(customResources, 'cfnEventAPIKey', {
    apiId: cfnEventAPI.attrApiId,
    description: 'realtime leaderboard demo',
})
TypeScript

AWS AppSync Events は最近リリースされたため、現時点では L1 コンストラクトのみが利用可能です。より簡潔なコンストラクト (L2) は現在開発中です。L2 が利用可能になれば、この記事を更新します。

この API イベントが認証に API キーを使用していることに注目してください。これは開発目的とテストには適していますが、ドキュメントでは、AWS Identity and Access Management (IAM)、Amazon Cognito、OIDC、AWS Lambda の権限を含む認証モードの使用方法も示されています。

バックエンドリソースの作成の最後のステップは、解決された値をフロントエンドアプリケーションに渡すことです。幸いなことに、Amplify の JavaScript ライブラリは、必要な値が設定されたフォーマットで渡されている限り、イベントへの接続、公開、サブスクライブが簡単にできるようにアップデートされています。

amplify/backend.ts ファイルの最後に、次のコードを貼り付けてください。

backend.addOutput({
    custom: {
        events: {
            url: `https://${cfnEventAPI.getAtt('Dns.Http').toString()}/event`,
            api_key: cfnApiKey.attrApiKey,
            aws_region: customResources.region,
            default_authorization_type: AuthorizationType.API_KEY,
        },
    },
})
TypeScript

バックエンドをデプロイする準備ができました。これにより、プロジェクトのルートに amplify_outputs.json ファイルが作成され、フロントエンドを構成するために必要な出力が含まれます。

AWS アカウントを設定していない場合は、Amplify のこちらのガイドに従って認証情報を設定してください。

次のコマンドを実行してデプロイします。

npx ampx sandbox 
# npx ampx sandbox --profile your-profile-name
Bash

AWS Amplify を利用したイベント API への接続、公開、サブスクライブ

このプロジェクトのリポジトリは、すでに Amplify で構成されています。これは components/configureAmplify.tsx ファイルに示されており、app/layout.tsx ファイルで利用されています。

あとは、フロントエンドから関連するメソッドを呼び出して、バックエンドが機能することをテストするだけです。

設計上、AWS AppSync Events は Amplify ライブラリを必要としません。ネイティブの WebSocket プロトコルを使用してクライアントを構成することが可能です。Amplify は単に、ボイラープレートを防ぐための便利なソリューションを提供するだけです。

app/page.tsx ファイルでは、バックエンドで作成した default という名前のチャネルへの接続を設定する必要があります。また、クライアントでセグメントを作成することもできます。この動作を確認するため、useEffect内で次のコードでアプリケーションに接続します。

const channelConnect = async () => {
    try {
        const channel = await events.connect('/default/leaderboard')
        channelRef.current = channel 

        channel.subscribe({
            next: handleNewData,
            error: (err) => console.log(err),
        })
    } catch (e) {
        console.log('Error connecting to channel: ', e)
    }
}
TypeScript

Amplify の events.connect 関数は、default/leaderboard チャネルへの接続を確立するために使用されます。これにより、そのチャネルからの受信データをサブスクライブできるようになります。

「Simulate Scoring」ボタンをユーザーがクリックするたびに、イベントを発行します。これは同じページから発生していますが、Lambda 関数や他のシステムやアプリケーションからも簡単に追加できます。

データの公開には events.post 関数が使用され、app/page.tsx ファイル内の次のコードで示されているように、ランダムなプレーヤーが選択され、ランダムなスコア更新が与えられ、イベント API に投稿されます。

const handlePublish = async () => {
    for (let i = 0; i <= 10; i++) {
        const randomItem =
            leaderboardData[Math.floor(Math.random() * leaderboardData.length)].id
        const randomScore = Math.floor(Math.random() * 20)

        await events.post('/default/leaderboard', {
            id: randomItem,
            score: randomScore,
        })
        await new Promise((resolve) => setTimeout(resolve, 100))
    }
}
TypeScript

まとめ

この記事では、AWS AppSync Events がグリーンフィールドとブラウンフィールドの両方のアプリケーションで使用できるシンプルな Pub/Sub ソリューションを提供することを説明しました。また、Amplify Gen 2 を使用して L1 コンストラクタを導入し、開発者が新しく発表された機能を IaC でよりすばやく使用できるようになることを紹介しました。

このアプリケーションはシンプルなデモンストレーションではありましたが、AWS AppSync Events は、ゲームやライブオークションなど大規模なユーザが見込まれるサービスにまで適用できることに注意が必要です。

月 250,000 件のリアルタイムイベント API 操作を無料で利用できます。AWS AppSync Events の詳細については、ドキュメントページをご覧ください。価格に関する詳細は、価格ページをご確認ください。

翻訳は Solutions Architect の 吉村 が担当しました。