Amazon Web Services ブログ

フロントエンド開発者のための AWS Amplify の 6 つの新しいリリース

AWS Amplify チームはコミュニティからのリクエストに答える 6 つの新しいリリースを紹介します。本記事では、ドキュメントサイトの改善、Next.js 14 のサポート、カスタム認証プロバイダ、React Native のソーシャルサインイン、UI コンポーネントを紹介します。

新しい ドキュメントサイト

docs.amplify.aws にアクセスして、Amplify の新しいドキュメントサイトをご覧ください。このサイトでは、Amplify UI コンポーネントを使用してビジュアルを全面的に再設計しています。コンテンツを再編成して発見しやすくし、必要な情報を見つけやすくしました。新しいアーキテクチャでは、CLI やライブラリのような特定のツールではなく、「アプリに認証を追加する」というようなユースケースを中心にドキュメントを構成しています。これにより、Amplify でフルスタックアプリケーションを構築する方法をより簡単に学べるようになることを期待しています。また、Amplify のすべての部分と、それらをどのように一緒に使うことができるかを理解するのに役立つことを目的とした、新しく作成した Amplify の仕組みのページもあります。

具体的な変更については、ドキュメントをご覧ください。

Next.js 14 のサポート

ホスティングと JavaScript ライブラリで Next.js 14 のサポートを追加しました。今週初め、Amplify JavaScript ライブラリのメジャーアップデートをリリースしました。v6 では、Next.js 14 の最も人気のある新機能の 1 つである Server Actions を含む、Next.js 14 との完全な互換性があります。新しい generateServerClientUsingCookies 関数により、Server Actionsでサーバーコンポーネントを安全に実行できるようになりました。

すでに AWS AppSync バックエンドに接続されている Next.js 14 アプリケーションで、この機能を実際に使ってみましょう。

まず、新しく utils/server-utils.ts ファイルを追加します。

// server-utils.ts

import { cookies } from "next/headers";
import { generateServerClientUsingCookies } from "@aws-amplify/adapter-nextjs/api";

import config from "@/amplifyconfiguration.json";

export const serverClient = generateServerClientUsingCookies({
  config,
  cookies,
});

サーバーコンポーネントの投稿を削除する Server Actions を作ってみましょう。

// page.tsx
import * as mutations from "@/graphql/mutations";
import { serverClient } from "@/utils/server-utils";
// ...
  async function deletePost(formData: FormData) {
    "use server";
    const id = formData.get("postId")?.toString();

    if (id) {
      const { errors } = await serverClient.graphql({
        query: mutations.deleteTodo,
        variables: {
          input: {
            id,
          },
        },
      });

      if (errors) {
        // handle errors
      }
    }
}

この delete 関数は、削除用の postId を取得する Server Action として使用されます。これにより、サーバー上でフォーム送信を処理し、id を取得して入力変数に渡すことができます。

Amplify Hosting では、Next.js 14 にも対応しました。この新機能を使用するには、アプリの最初のデプロイである場合、カスタムビルドイメージの値として amplify:al2023 を設定します。逆に、アプリがすでにデプロイされている場合は、ドロップダウンから Amazon Linux: 2023 イメージを選択します。

このイメージには、Next.js 14 が必要とする Node 18 の最新バージョンが含まれています。すでにNode 18を搭載したイメージを使用している場合は、ビルド設定に nvm use 18 を追加することも可能です。

Next.js で Amplify を使う方法はこちら

カスタム認証プロバイダ

Amplify Auth にカスタムトークンプロバイダを追加できるようになりました。これにより、例えばOIDCのような独自のトークンサービスを利用している場合に、独自のカスタムトークンプロバイダを作成することができます。これで、Amplify.configure メソッド呼び出しでトークンを提供できるようになります。以下はそのサンプルです。

import { Amplify } from 'aws-amplify';
import { TokenProvider, decodeJWT } from 'aws-amplify/auth';

// ...

const myTokenProvider: TokenProvider = {
  async getTokens({ forceRefresh } = {}) {
    if (forceRefresh) {
      // try to obtain new tokens if possible
    }

    const accessTokenString = '<insert JWT from provider>';
    const idTokenString = '<insert JWT from provider>';
    
    return {
      accessToken: decodeJWT(accessTokenString),
      idToken: decodeJWT(idTokenString),
    };
  },
};

Amplify.configure(awsconfig, {
  Auth: {
    tokenProvider: myTokenProvider
  }
});

ユーザプールフェデレーションを使用せずに、Cognito Federated Identities から直接独自のカスタムクレデンシャルプロバイダを作成することもできます。この場合も、Amplify.configure メソッド呼び出しによって提供します。これがどのように機能するかの例を以下に示します。

import { Amplify } from 'aws-amplify';
import {
  fetchAuthSession,
  CredentialsAndIdentityIdProvider,
  CredentialsAndIdentityId,
  GetCredentialsOptions,
  AuthTokens,
} from 'aws-amplify/auth';

// Note: This example requires installing `@aws-sdk/client-cognito-identity` to obtain Cognito credentials
// npm i @aws-sdk/client-cognito-identity
import { CognitoIdentity } from '@aws-sdk/client-cognito-identity';

// You can make use of the sdk to get identityId and credentials
const cognitoidentity = new CognitoIdentity({
  region: '<region-from-config>',
});

// Note: The custom provider class must implement CredentialsAndIdentityIdProvider
class CustomCredentialsProvider implements CredentialsAndIdentityIdProvider {

  // Example class member that holds the login information
  federatedLogin?: {
    domain: string,
    token: string
  };

  // Custom method to load the federated login information
  loadFederatedLogin(login?: typeof this.federatedLogin) {
    // You may also persist this by caching if needed
    this.federatedLogin = login;
  }

  async getCredentialsAndIdentityId(
    getCredentialsOptions: GetCredentialsOptions
  ): Promise<CredentialsAndIdentityId | undefined> {
    try {

      // You can add in some validation to check if the token is available before proceeding
      // You can also refresh the token if it's expired before proceeding

      const getIdResult = await cognitoidentity.getId({
        // Get the identityPoolId from config
        IdentityPoolId: '<identity-pool-id-from-config>',
        Logins: { [this.federatedLogin.domain]: this.federatedLogin.token },
      });

      const cognitoCredentialsResult = await cognitoidentity.getCredentialsForIdentity({
        IdentityId: getIdResult.IdentityId,
        Logins: { [this.federatedLogin.domain]: this.federatedLogin.token },
      });

      const credentials: CredentialsAndIdentityId = {
        credentials: {
          accessKeyId: cognitoCredentialsResult.Credentials?.AccessKeyId,
          secretAccessKey: cognitoCredentialsResult.Credentials?.SecretKey,
          sessionToken: cognitoCredentialsResult.Credentials?.SessionToken,
          expiration: cognitoCredentialsResult.Credentials?.Expiration,
        },
        identityId: getIdResult.IdentityId,
      };
      return credentials;
    } catch (e) {
      console.log('Error getting credentials: ', e);
    }
  }
  // Implement this to clear any cached credentials and identityId. This can be called when signing out of the federation service.
  clearCredentialsAndIdentityId(): void {}
}

// Create an instance of your custom provider
const customCredentialsProvider = new CustomCredentialsProvider();
Amplify.configure(awsconfig, {
  Auth: {
    // Supply the custom credentials provider to Amplify
    credentialsProvider: customCredentialsProvider
  },
});

カスタム認証プロバイダの詳細はこちら

React Native ソーシャルサインイン

Authenticator は自動的に amplify auth の設定を引き継ぐので、ソーシャルサインインを使用するために @aws-amplify/ui-react-native@aws-amplify/rtn-web-browser パッケージの新バージョンを入手する以外に変更を加える必要はありません。

React Native のソーシャルサインインの設定方法についてはこちら

アカウント設定コンポーネント

Amplify UI には、サインインとサインアップ機能を提供する Authenticator コンポーネントと同様のフローでユーザーの認証設定を更新するための 2 つのコンポーネントがあります。これらのコンポーネントはクラウドに接続されているため、Amplify のバックエンドで動作させるために追加のロジックを実装する必要はありません。これらのコンポーネントは完全にカスタマイズ可能で、テーマ設定も可能です。 ChangePassword コンポーネントは、ユーザーが新しいパスワードを入力して確認することで、現在のパスワードを変更できるようにします。

DeleteUser コンポーネントは、ユーザが自分のアカウントを完全に削除することを可能にします。

アカウント設定コンポーネントの詳細はこちら

Amplify UI React v6

Amplify JS v6 のリリースに合わせて、すべての Amplify UI パッケージを Amplify JS v6 を使用するように更新しました。 Amplify JS v6 が提供するのと同様のバンドルサイズの改善に加えて、UI はいくつかの依存関係を削除し、コードベースをクリーンアップすることで、いくつかのサイズの改善も行いました。

Tabs コンポーネントの再構築

Tabs コンポーネントは、よりコンポーザブルでカスタマイズできるように、一から作り直されました。

<Tabs.Container defaultValue="Tab 1">
    <Tabs.List>
       <Tabs.Item value="Tab 1">Tab 1</Tabs.Item>
       <Tabs.Item value="Tab 2">Tab 2</Tabs.Item>
       <Tabs.Item value="Tab 3" isDisabled>
          Tab 3
       </Tabs.Item>
     </Tabs.List>
     <Tabs.Panel value="Tab 1">Tab 1 content</Tabs.Panel>
     <Tabs.Panel value="Tab 2">Tab 1 content</Tabs.Panel>
     <Tabs.Panel value="Tab 3" isDisabled>
       Tab 1 content
    </Tabs.Panel>
</Tabs.Container>

Tabs をもっとシンプルに使うこともできます。

<Tabs
    defaultValue={'Tab 1'}
    items={[
      { label: 'Tab 1', value: 'Tab 1', content: 'Tab content #1' },
      { label: 'Tab 2', value: 'Tab 2', content: 'Tab content #2' },
      { label: 'Tab 3', value: 'Tab 3', content: 'Tab content #3' },
    ]}
  />

Expander の再構築 (現在は Accordion)

Tabs と同じように、Expander コンポーネントも再構築し、セマンティックな HTML 要素である<details><summary> を使えるようにしました。また、他の UI ライブラリと合わせるために、コンポーネントの名前を Accordion に変更しました。

<Accordion.Container>
  <Accordion.Item value="Accordion-item">
    <Accordion.Trigger>
      What is an Accordion?
      <Accordion.Icon />
    </Accordion.Trigger>
    <Accordion.Content>
      An Accordion contains all the parts of a collapsible section.
    </Accordion.Content>
  </Accordion.Item>
  <Accordion.Item value="unique-value">
    <Accordion.Trigger>
      This is the item title
      <Accordion.Icon />
    </Accordion.Trigger>
    <Accordion.Content>
      The `children` of the Accordion are displayed here.
    </Accordion.Content>
  </Accordion.Item>
</Accordion.Container>

Tabs コンポーネントと同様に、よりシンプルな API で使用できます。

<Accordion
  items={[
    {
      trigger: 'Is it accessible?',
      value: 'accessible',
      content: 'Yes! It uses HTML native elements: <details> and <summary>.'
    },
    {
      trigger: 'Can I customize the styling?',
      value: 'styling',
      content: 'Of course! See the section on CSS Styling below.'
    },
    {
      trigger: 'Is it a great way to organize content?',
      value: 'content',
      content: 'Most definitely!'
    }
  ]}
/>

詳細はマイグレーションガイドをご覧ください。

CSS レイヤーと分割ファイル

CSS レイヤーに慣れていない場合、CSS レイヤーは、CSS を別々のレイヤーにまとめることで、CSS セレクタがより高い特異性 (specificity) を持っていなくても、特定のレイヤーが優先されるようにし、特異性の問題を解決するのに役立ちます。CSS レイヤーがブラウザで広く採用されるようになったので、CSS レイヤーを利用するための新しい CSS ファイルをいくつか追加しました。CSS レイヤーはオプトインなので、例えば .css.layer.css に変更してください。

import '@aws-amplify/ui-react/styles.layer.css';

また、スタイルのどの部分をインポートするかをコントロールできるように、CSS ファイルを分割しました。各コンポーネントには独自の CSS ファイルと、Amplify UI スタイルのベースとなるCSS ファイル、そしてリセット CSS ファイルがあります。これらのファイルはこのように使うことができます。

import '@aws-amplify/ui-react/reset.layer.css' // global CSS reset
import '@aws-amplify/ui-react/base.layer.css' // base styling needed for Amplify UI
import '@aws-amplify/ui-react/button.layer.css' // component specific styles

テーマの更新

Amplify UI のテーマ化もより簡単になりました。任意のデザイントークンをテーマに追加し、コンポーネントで参照、使用できるようになりました。テーマのプライマリカラーとセカンダリカラーを設定するには、それぞれの色合いを値 (例 : 10, 20, 40, 60, 80, 90, 100) にマッピングする必要があり、面倒でした。今では、例えば、テーマのルートに primaryColor: 'red' を追加するだけで設定することができます。

const theme = createTheme({
 primaryColor: 'red',
 secondaryColor: 'green',
 });

Amplify UIについてもっと知る

まとめ

AWS Amplify はフルスタックアプリケーションをより速く構築するための 6 つの新機能を発表しました。私たちのすべてのローンチはコミュニティによってインスパイアされているので、アイデアやフィードバックがあれば GitHubDiscord からご連絡ください。Amplify でのビルド方法の詳細については、ドキュメントをご覧ください。

本記事は「6 New AWS Amplify Launches for Frontend Developers」を翻訳したものです。

翻訳者について

稲田 大陸

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