メインコンテンツまでスキップ

AWS Amplify JavaScript ライブラリ v6 がリリースされたので v5 からマイグレーションしてみた

· 約10分
Chikako Oyanagi

11 月 15 日に AWS Amplify JavaScript ライブラリ v6 がリリースされました。早速 Amplify ライブラリ v5 で開発したコードを v6 にマイグレーションしたので、どのような修正を行ったかを紹介します。

AWS Amplify とは

AWS Amplify は AWS でフルスタックアプリケーションを簡単に構築できるフルスタックの開発フレームワークです。Amplify CLIAmplify Web HostingAmplify StudioAmplify LibrariesAmplify UI Components といったツールやサービスで構成されていて、全てを利用することも、あるいはユースケースに合わせて一部を利用することもできる柔軟性を備えています。

今回マイグレーションを行ったアプリケーションは React で実装した Single-page Application で、Amplify LibrariesAmplify UI Components を利用しています。ライブラリの利用用途は主に Cognito との連携と AWS_IAM オーサライザーを設定した API Gateway との連携です。このアプリケーションで利用する Cognito や API Gateway は Amplify CLI を使わず手動でデプロイしているため、フロントエンドのコード内で Amplify.configure() を呼んで Cognito インスタンスのユーザープール ID や API エンドポイントをセットしています。これにより、Amplify のライブラリと Cognito や API が連携できるようになります。

マイグレーションの手順

マイグレーションは下記の手順で実施しました。

  • Amplify LibrariesAmplify UI Components ライブラリのアップデート
  • Amplify Libraries のアップデートで発生した TS エラーに対応
  • Amplify UI Components のアップデートで発生したスタイル崩れに対応

Amplify ライブラリのアップデート

アプリケーションに対し、npm-check-updates を使ってアップデート可能なライブラリを確認します。下記の通り aws-amplify は v5.3.3、@aws-amplify/ui-react は v.5.0.4 を利用しています。今回はそれぞれ v6.0.5 と v6.0.3 にアップデートします。

% npx npm-check-updates
Checking /repo/frontend/package.json
[====================] 14/14 100%

aws-amplify ^5.3.3 → ^6.0.5
@aws-amplify/ui-react ^5.0.4 → ^6.0.3

% npx npm-check-updates -u
Run npm install to install new versions.

% npm install
added 431 packages, and audited 432 packages in 19s

46 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

アップデート後のソースコードを確認すると、数箇所で TS エラーが見つかりました。その箇所を修正していきます。

コード修正

1. Amplify.configure に渡すデータを修正

発生した TS エラー

Type '{ identityPoolId: string; region: string; userPoolId: string; userPoolWebClientId: string; }' is not assignable to type 'AuthConfig | undefined'.
Object literal may only specify known properties, and 'identityPoolId' does not exist in type 'AuthConfig'.ts(2322)
Type '{ endpoints: { name: string; endpoint: string; region: string; }[]; }' is not assignable to type 'APIConfig | undefined'.
Object literal may only specify known properties, and 'endpoints' does not exist in type 'APIConfig'.ts(2322)

修正内容

Amplify.configure で渡すデータ構造がアップデートで変更されています。v6 では Auth の下に Cognito の階層が増えています。また userPoolWebClientIduserPoolClientId に変わっています。APIendpoints から REST に変更されていて、v5 で name にセットしていた値は v6 ではキーとして設定する必要があります。

v5

Amplify.configure({
Auth: {
identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',
userPoolId: 'XX-XXXX-X_abcd1234',
userPoolWebClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
region: 'XX-XXXX-X',
},
API: {
endpoints: [
{
name: 'restApi',
endpoint: 'https://1234567890-abcdefgh.amazonaws.com',
region: 'XX-XXXX-X',
},
],
},
});

v6

Amplify.configure({
Auth: {
Cognito: {
identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',
userPoolId: 'XX-XXXX-X_abcd1234',
userPoolClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
},
},
API: {
REST: {
restApi: {
endpoint: 'https://1234567890-abcdefgh.amazonaws.com',
region: 'XX-XXXX-X',
},
},
},
});

2. API の呼び出し部分を修正

発生した TS エラー

Module '"aws-amplify"' has no exported member 'API'.ts(2305)

修正内容

API Gateway の API の呼び出しの実装は、v5 の場合は aws-amplifyAPI を利用していましたが、v6 では代わりに aws-amplify/apigetpost などの関数を利用します。

v5

import { API } from 'aws-amplify';

try {
const response = await API.get('restApi', '/items', {});
setItems(response);
} catch (error) {
console.error(JSON.stringify(error));
if (error instanceof Error) {
setErrorMessage(error.message);
}
}

v6

import { get } from 'aws-amplify/api';

try {
const restOperation = get({
apiName: 'restApi',
path: '/items',
});
const response = await restOperation.response;
const json = await response.body.json();
setItems(json as Item[]);
} catch (error) {
console.error(error);
if (error instanceof Error) {
setErrorMessage(error.message);
}
}

変更されたのは API(REST) だけではなく、例えば API(GraphQL) の場合は API から client.graphql に置き換わっています。

v5

await API.graphql(graphqlOperation(createTodo, { input: todo }));

v6

const client = generateClient();

const newTodo = await client.graphql({
query: createTodo,
variables: { input: todoDetails }
});

他のサービスに関しての変更の詳細はマイグレーションのページがあるのでそちらを参考にしてください。

3. ユーザーの attributes の取得方法を修正

発生した TS エラー

Property 'attributes' does not exist on type 'AuthUser'.ts(2339)

修正内容

email を取得するために user オブジェクトの attributes プロパティを参照していましたが、v6 の user オブジェクトは attributes が存在しないため、専用の fetchUserAttributes という関数を使って取得します。

v5

import { useAuthenticator } from '@aws-amplify/ui-react';

const { user, signOut } = useAuthenticator((context) => [context.user]);
conosole.log(user.attributes?.email);

v6

import { fetchUserAttributes } from 'aws-amplify/auth';

const attributes = await fetchUserAttributes();
console.log(attributes.email ?? '');

aws-amplify/auth 配下には他にも JWT などセッション情報を取得するための fetchAuthSession や、signInsignOut などの関数がまとまっています。v5 で aws-amplifyAuth を利用していた部分は aws-amplify/auth への置き換えが必要になりそうです。

4. UI コンポーネントのスタイルやクラスに関する変更

上記の修正を加えたところでエラーが消え、画面が表示されるようになりました。

しかしスタイルの崩れやスタイルが当たっていない箇所があるようです。Amplify UI Componentsマイグレーションのページ を参考しながら修正します。

  • カラートークンの namespcae が変更されている

tokens.colors.brand.primarybrand namespace が消え、tokens.colors.primary に変更されていました。これに伴い、該当する CSS 変数名からも brand が消えているため、この変数を利用していた箇所を修正する必要がありました。

v5

td:first-child {
color: var(--amplify-colors-brand-primary-80);
}

td:last-child {
color: var(--amplify-colors-brand-secondary-80);
}

v6

td:first-child {
color: var(--amplify-colors-primary-80);
}

td:last-child {
color: var(--amplify-colors-secondary-80);
}
  • コンポーネントのクラス名が変更されている

v6 でいくつかのコンポーネントのクラス名が変更されています。これらのクラス名を override するなどで参照している場合は修正が必要です。本記事のアプリケーションではメニューコンポーネントのスタイル定義に、amplify-menu-content クラスを利用しているため、amplify-menu__content に変更する必要があります。実際には今後同様の変更が行われても問題が起こらないよう新しいクラスを定義し、そちらでスタイリングを行うように修正しました。

v5

.amplify-menu-content {
..
}

v6

.amplify-menu__content {
...
}

または

.header-menu { //独自クラス
...
}
<Menu className="header-menu" />

以上二点の修正を加えることで期待した通りのスタイルが適用されるようになりました。

今回のアプリケーションでは触れていませんが、AuthenticatorAccordionTabs コンポーネントもアップデートにより変更があります。記事の最後に記載したリファレンスからアップデート内容をご確認ください。

おわりに

本記事では Amplify ライブラリのアップデートに伴い以下のコードの修正を行いました。

  • Amplify.configure に渡すデータの形式を v6 の形式に合わせて修正
  • API Gateway(REST) を呼び出すコードを aws-amplify モジュールの API から aws-amplify/api モジュールの get に変更
  • ユーザーの attributes の取得方法の変更
  • Amplify UI コンポーネントのクラス名とカラートークン名のアップデートを元にスタイル定義を修正

Amplify ライブラリのアップデートを行う際の参考となれば幸いです。また、PubSub 実装など今回説明していない部分で Amplify ライブラリを利用している場合は、下記のマイグレーションのページを参考にしてください。