@gomi_ningen's Website

AppSync GraphQL API を用いて手軽に Subscription を試す

AppSync GraphQL API への Mutation, Subscription を通して簡単な メッセージの Pub/Sub を試す手順をメモしておきます。GraphQL API の Subscription をお手軽に試してみたい方や、テスト目的のモック Mutation, Subscription を手軽に作りたいときに便利な手順かと思います。

スキーマの作成

AppSync GraphQL API を作成したのち、まずはスキーマの作成を行います。今回はできるだけ細かいことを省いて Mutation, Subscription 実験用の GraphQL API を作成したいため以下のように簡単なものとなります。

type Message { messageId: String! message: String! } type Mutation { sendMessage(message: String!): Message } type Subscription { addedMessage: Message @aws_subscribe(mutations: ["sendMessage"]) } schema { mutation: Mutation subscription: Subscription }

上記のスキーマからおわかりいただけるかと思いますが、Mutation: sendMessage にて単純な文字列のメッセージを送信します。messageId, message を含む Message が戻り値となります。

また Subscription: messageAdded を購読すると sendMessage が呼び出された際に Message が飛んでくる仕組みとなります。このあたりはスキーマ中の @aws_subscribe にあたる箇所にて実現しています。

これは AppSync の GraphQL スキーマサブスクリプションディレクティブ というものとなります。

データソース/リゾルバーの作成と設定

前述のとおりサブスクリプションディレクティブにより sendMessage にてメッセージが送信されると、その内容が addedMessage の購読者にリアルタイムに通知される仕組みとなっています。

したがって sendMessage は単純に受け取った message に加えて messageId を追加して Message 形の値を返却すればよいこととなります。

また適当な UUID はリゾルバーのマッピングテンプレートユーティリティー: $util.autoId() で生成できるため、今回特段 Lambda などのデータソースを設定する必要がなく、NONE タイプのデータソースとリゾルバーマッピングテンプレートにて対応できる形となります。

したがって、残作業は以下の 2 つとなります。

  1. NONE タイプのデータソースを作る
  2. 作成したデータソースを sendMessage にアタッチし、リクエストマッピングテンプレート、レスポンスマッピングテンプレートをそれぞれ以下のように設定する
// request mapping template { "version": "2017-02-28", "payload": { "messageId": "$util.autoId()", "message": "$context.arguments.message" } } // response mapping template $util.toJson($context.result)

以上にて AppSync GraphQL にて Mutation, Subscription を利用したメッセージの Pub/Sub の仕組みの準備が完了しました。

マネジメントコンソールから Pub/Sub を試す

AppSync GraphQL API はマネジメントコンソール上から手軽に動作検証可能なため、作成した API の画面から [クエリ] ページに飛び、該当の URL でウィンドウを 2 つ開きます。

片方のウィンドウにてあらかじめ Subscritpion を行っておきます。その後、もう片方のウィンドウからメッセージを発行する Mutation を行うと購読している側のウィンドウにも送信したメッセージが表示されることがわかる形と思います。

# Subscription subscription MySubscritpion { messageAdded { messageId message } } # Mutation mutation { sendMessage(message: "Hello") { messageId message } }

wscat から Pub/Sub を試す

wscat コマンドを利用して WebSocket で GraphQL リアルタイムエンドポイントと直接会話することも可能。

GraphQL リアルタイムエンドポイントの主要なオペレーションはドキュメント: リアルタイム WebSocket クライアントを構築する に記載されている以下のようなものとなる。

  1. 接続の初期化 (connection_init)
  2. 接続確認応答 (connection_ack)
  3. サブスクリプション登録 (start)
  4. サブスクリプション確認応答 (start_ack)
  5. サブスクリプションの処理 (data)
  6. サブスクリプションの登録解除 (stop)

実際に wscat の導入から GraphQL リアルタイムエンドポイントへの接続・切断までの流れは以下のとおり

$ npm install -g wscat ... $ GRAPHQL_HOST= $ REALTIME_HOST= $ API_KEY= $ $ header=`echo "{\"host\":\"$GRAPHQL_HOST\",\"x-api-key\":\"$API_KEY\"}" | base64` $ wscat -s graphql-ws -c "wss://$REALTIME_HOST?header=$header&payload=e30=" Connected (press CTRL+C to quit) > {"type":"connection_init"} < {"type":"connection_ack","payload":{"connectionTimeoutMs":300000}} < {"type":"ka"} > {"id":"1","payload":{"data":"{\"query\":\"subscription {\\n messageAdded {\\n message\\n messageId\\n }\\n}\\n\",\"variables\":{}}","extensions":{"authorization":{"host":"<GRAPHQL_HOST>","x-api-key":"<API_KEY>"}}},"type":"start"} < {"id":"1","type":"start_ack"} < {"type":"ka"} < {"type":"ka"} < {"id":"1","type":"data","payload":{"data":{"messageAdded":{"message":"hello","messageId":"69378263-6562-4770-b057-3062e22e0f07"}}}} < {"type":"ka"} > {"type":"stop","id":"1"} < {"id":"1","type":"complete"}

Amplify SDK から Pub/Sub を試す

適当なウェブアプリケーションにて yarn add aws-amplify をしたのち、以下を実行すると messageAdded を購読できる。sendMessage するとデベロッパーコンソールにメッセージが出力される

import { Amplify, API } from 'aws-amplify' Amplify.configure({ aws_project_region: '<REGION>', aws_appsync_graphqlEndpoint: '<ENDPOINT>', aws_appsync_authenticationType: 'API_KEY', aws_appsync_apiKey: '<API_KEY>', }) const subscription = API.graphql({ query: ` subscription { messageAdded { message messageId } } `, }).subscribe({ next: (message) => { console.log(JSON.stringify(message?.value?.data?.messageAdded)) }, error: (error) => console.warn(error), })

Copyright © 53ningen.com