こんにちは、広野です。
手持ちの React アプリで aws-amplify と @aws-amplify/ui-react モジュールのバージョン 5 を使用していたのですが、バージョン 6 にアップデートしてみました。アプリ内の設定フォーマットや、組み込みの AWS サービス呼び出し用モジュールに変更があったので結構手直しが入りました。ですがドキュメントから情報を探せば何とかなりました。
公式のドキュメントはこちらです。
変更点
私が経験した限りの変更点です。React アプリから以下の AWS サービスを呼び出していたので、その部分の紹介のみとなることをご了承ください。以降、それぞれの変更箇所にブレークダウンしていきます。
- Amazon Cognito
- Amazon S3
- AWS AppSync
- Amazon Kinesis Data Firehose
aws-amplify モジュールの設定は Amplify.configure というコードでアプリ内に記述します。これまで、連携する AWS サービスごとに設定フォーマットがバラバラだったので、それらが統一された感じがします。それに伴ってかわかりませんが、アプリ内で実際にサービスを呼び出すときの命令コードも変更が入っています。大きな仕様変更と言うよりは、書き方を変えただけという感じでした。
(共通) Amplify.configure の設定
App.js に記述していた設定に変更が入っています。特に Amazon Kinesis Data Firehose 用の設定が大きく変わりました。変更前と変更後のコードを記載し、変更箇所に赤線を引いておきます。
※パラメータは環境変数 (process.env.***) を使用しています。
※記述方法はいくつかのパターンがあります。
- 変更前
import React from 'react'; import { Amplify, Analytics, AWSKinesisFirehoseProvider } from 'aws-amplify'; //Cognito, S3, AppSync 連携設定 Amplify.configure({ Auth: { userPoolId: process.env.REACT_APP_USERPOOLID, userPoolWebClientId: process.env.REACT_APP_USERPOOLWEBCLIENTID, identityPoolId: process.env.REACT_APP_IDPOOLID, region: process.env.REACT_APP_REGION }, Storage: { AWSS3: { bucket: process.env.REACT_APP_AMPLIFYSTORAGE, region: process.env.REACT_APP_REGION } }, aws_appsync_graphqlEndpoint: process.env.REACT_APP_APPSYNC, aws_appsync_region: process.env.REACT_APP_REGION, aws_appsync_authenticationType: "AMAZON_COGNITO_USER_POOLS" }); //Kinesis Data Firehose 連携設定 Analytics.addPluggable(new AWSKinesisFirehoseProvider()); Analytics.configure({ AWSKinesisFirehose: { region: process.env.REACT_APP_REGION, bufferSize: 1000, flushSize: 100, flushInterval: 5000, // 5s resendLimit: 5 } });
- 変更後
import React from 'react'; import { Amplify } from 'aws-amplify'; //Cognito, S3, AppSync, Kinesis Data Firehose 連携設定 Amplify.configure({ Auth: { Cognito: { userPoolId: process.env.REACT_APP_USERPOOLID, userPoolClientId: process.env.REACT_APP_USERPOOLWEBCLIENTID, identityPoolId: process.env.REACT_APP_IDPOOLID } }, Storage: { S3: { bucket: process.env.REACT_APP_AMPLIFYSTORAGE, region: process.env.REACT_APP_REGION } }, API: { GraphQL: { endpoint: process.env.REACT_APP_APPSYNC, region: process.env.REACT_APP_REGION, defaultAuthMode: 'userPool' } }, Analytics: { KinesisFirehose: { region: process.env.REACT_APP_REGION, bufferSize: 1000, flushSize: 100, flushInterval: 5000, // 5s resendLimit: 5 } } });
Amazon Cognito
@amplify-ui/react と Amazon Cognito を連携させるコードは、かなり変わりました。必要な情報が公式ドキュメント内に分散されて書かれていたので、繋ぎ合わせるのに苦労しました。
私の場合は useAuthenticator を使用しているので、その記述の限りになりますこと、ご了承ください。useAuthenticator で Amazon Cognito の認証を経て、ユーザーの情報やトークンを取得する仕様が変わりました。
- 変更前
import React from 'react'; import { useAuthenticator } from '@aws-amplify/ui-react'; const { user, signOut } = useAuthenticator((context) => [context.user]);
この記述だけで、以下の情報が取れました。user の中に全て格納されていました。
- ユーザー名(メールアドレス)
- 所属 Cognito グループ → アプリ内権限分けで使用
- ID トークン (Base64 エンコード) → API Gateway の Cognito オーソライザーで使用
- 変更後
import React, { useState, useEffect } from 'react'; import { useAuthenticator } from '@aws-amplify/ui-react'; import { fetchAuthSession } from 'aws-amplify/auth'; const { user, signOut } = useAuthenticator((context) => [context.user]); //ステート定義 const [username, setUsername] = useState(); const [authToken, setAuthToken] = useState(); const [groups, setGroups] = useState(); //セッション情報取得 const getSession = async () => { const { tokens } = await fetchAuthSession(); setUsername(tokens?.idToken?.payload.email); setGroups(tokens?.idToken?.payload["cognito:groups"]); setAuthToken(tokens?.idToken?.toString()); }; useEffect(() => { getSession(); }, []);
変更前の記述だけでは欲しいユーザー情報またはセッション情報が取得できないため、赤線部分を追記しています。平たく言うと user の中にユーザーの所属グループや ID トークンは入らなくなりました。そのため、 fetchAuthSession というモジュールを新たに追加しています。※他の取得方法もありますので一例です。
- ユーザー名: tokens?.idToken?.payload.email ※メールアドレスをユーザー名にしているため。ユーザー名は user からも取れる。
- 所属 Cognito グループ: tokens?.idToken?.payload[“cognito:groups”]
- ID トークン: tokens?.idToken?.toString()
Amazon S3
Amazon S3 バケットに JSON データを送信し、ファイルとしてアップロードしておりました。当時の記事は以下です。これに対して書き方の変更が入りました。動作仕様は変わっていないように見えます。
- 変更前
import { Storage } from 'aws-amplify'; //AmplifyStorageにJSONデータを転送 const putFile = async () => { try { await Storage.put( "data.json", //S3に送信したデータファイルに付けるオブジェクト名 jsonData, //S3に送信したいJSONオブジェクトのデータ { level: "private", //private権限のフォルダに格納する progressCallback(progress) { setProgress(progress.loaded/progress.total); } } ); } catch (error) { alert("File uploading error occurred: " + error); } };
- 変更後
import { uploadData } from 'aws-amplify/storage'; //AmplifyStorageにJSONデータを転送 const putFile = async () => { try { const result = await uploadData({ key: "data.json", data: JSON.stringify(jsonData), //Blobまたはstring等でないと送れなくなった options: { accessLevel: "private", onProgress: ({ transferredBytes, totalBytes }) => { if (totalBytes) { setProgress(transferredBytes / totalBytes); } } } }).result; } catch (error) { alert("File uploading error occurred: " + error); } };
AWS AppSync
React アプリから AWS AppSync 経由でデータのやり取りをしていました。当時の記事は以下です。これに対して少しだけ書き方の変更が入りました。動作仕様は変わっていないように見えます。
- 変更前
import { API } from 'aws-amplify'; import gql from 'graphql-tag'; //クエリー const queryGetChat = gql` query queryChatdataByServiceid($serviceid: String!) { queryChatdataByServiceid(serviceid: $serviceid) { items { datetime user message } } } `; //メッセージ取得関数 const getChat = async () => { const res = await API.graphql({ query: queryGetChat, variables: { serviceid: serviceid }, authMode: "AMAZON_COGNITO_USER_POOLS" }); };
- 変更後
import { generateClient } from 'aws-amplify/api'; import gql from 'graphql-tag'; const client = generateClient(); //クエリー const queryGetChat = gql` query queryChatdataByServiceid($serviceid: String!) { queryChatdataByServiceid(serviceid: $serviceid) { items { datetime user message } } } `; //メッセージ取得関数 const getChat = async () => { const res = await client.graphql({ query: queryGetChat, variables: { serviceid: serviceid } }); };
Amazon Kinesis Data Firehose
Amazon Kinesis Data Firehose の場合は、データ型の仕様に変更が入っています。以下変更前、変更後の記述方法の違いを見て頂ければと思います。data は送信する JSON データだと思って下さい。
- 変更前
import { Analytics } from 'aws-amplify'; Analytics.record({ data: JSON.stringify(data), streamName: process.env.REACT_APP_FIREHOSE_STREAMNAME_ACTIVITYLOG }, "AWSKinesisFirehose");
- 変更後
import { record } from 'aws-amplify/analytics/kinesis-firehose'; record({ data: data, streamName: process.env.REACT_APP_FIREHOSE_STREAMNAME_ACTIVITYLOG });
変更前は data を JSON.stringify でテキストに変更していましたが、変更後は JSON オブジェクトをそのまま送らないとエラーになります。
まとめ
いかがでしたでしょうか。
公式ドキュメントを見ながら四苦八苦して動く状態にできたので、本記事が皆様の参考になれれば幸いです。