Amazon Web Services ブログ

AWS Amplify が効果を発揮する Next.js の 5 つの機能

Next.js は、React アプリのサーバーサイドレンダリングと静的サイト生成を可能にする、人気の React フレームワークです。フロントエンドの Web およびモバイル開発者が AWS 上で迅速かつ容易にフルスタックアプリケーションを構築できるようにする目的で構築されたツールおよび機能のセットである AWS Amplify と組み合わせると、開発者は本当に強力なアプリを構築することができます。

本記事では AWS Amplify が効果を発揮する Next.js の 5 つの機能を紹介します。

1. データフェッチと API

Next.js は静的サイト生成(SSG)、サーバーサイドレンダリング(SSR)、クライアントサイドレンダリング(CSR)、インクリメンタル静的再生成(ISG)の 4 つの主要なデータ取得方法を提供しています。

AWS Amplify を使うことで Amazon DynamoDB をプロビジョニングし、Amplify Libraries を使って AWS AppSync を通じてデータを Query したり Mutationすることが出来ます。

例えば、Query、Mutation、Subscription を含む Todo アプリケーションのスキーマを定義します。Query は API からTodo をフェッチすることができます。Mutation は Todo の作成、更新、削除をできます。Subscription は他のユーザーによって Todo が追加、更新、または削除されたときに、アプリがリアルタイムの更新を受け取ることができます。AWS Amplify は、マネージド GraphQL サーバーである AWS AppSync を使用しています。AWS AppSync は、Amazon DynamoDB のような NoSQL データベースなどの異なるデータソースに接続することで、GraphQL 操作の解決に対応します。Subscription については、AWS AppSync は WebSocket を使用して、サーバーからサブスクライブしているクライアントに対してリアルタイムでデータをプッシュします。これによって Todo アプリは、API をポーリングして変更を確認することなく、最新の Todo を取得することが出来ます。

Next.js 13.4 以前では、以下のようにルーティングは Pages Router を通して行われ、ビルド時に静的データを取得し、データをページと一緒にプリレンダリングしていました。

// pages/todos.js
import { Amplify, API, graphqlOperation } from 'aws-amplify'
import { listTodos } from '../graphql/queries'
import awsExports from "../aws-exports"

Amplify.configure(awsExports)

export default function Todos(props) {
  const todos = props.data.listTodos.items
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.name}</li>
      ))}
    </ul>
  )
}

export async function getStaticProps() {
  const { data } = await API.graphql(graphqlOperation(listTodos))
  return { props: { data } }
}

SSR 用のページを実装し、各リクエストでデータを取得するには、同じコンポーネントを使用できますが、getStaticProps の代わりに getServerSideProps を使用して、データはサーバーで取得され、最初のレンダーにバンドルされることになります。

Next.js 13.4 では、デフォルトのルーティングは、Next.js 13 で初めて導入された React Server Componentで構築された App Router を介して行われ、共有レイアウト、入れ子ルーティング、ロードステート、エラー処理などをサポートしています。

以下のコードは Next.js 13.4 以降の React Server Componentの async/await を使用した例です。先程のコードとの違いは、getStaticProps を使わずに、API.graphql への待機呼び出しがコンポーネント定義に含まれている点です。

// app/page.js
import { Amplify, API, graphqlOperation } from 'aws-amplify'
import { listTodos } from '../graphql/queries'
import awsExports from "../aws-exports"

Amplify.configure(awsExports)

export default async function Todos(props) {
  const { data } = await API.graphql(graphqlOperation(listTodos))
  const todos = data.listTodos.items
  
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.name}</li>
      ))}
    </ul>
  )
}

2. 認証・認可

Next.js 自体は 認証・認可の機能を持っていませんが、AWS Amplify を使うことで、サポートされている認証プロバイダーのいずれかを使って、Next.js アプリにユーザーログイン、サインアップ、管理を追加できます。

AWS Amplify は、Amazon Cognito をメイン認証プロバイダとすることで、Google、Facebook などと連携できます。これにより、Next.js アプリにユーザーログイン、サインアップ、トークン更新、多要素認証(MFA)などの認証フローを数行のコードで迅速かつ容易に実装でき、ユーザーは任意のプロバイダでサインインすることができます。Amplify Libraries は、ユーザープール、ユーザー認証情報、および認証トークンの生成を処理し、アプリのさまざまな部分への安全なアクセスを可能にします。

Amplify UI React の 接続踏みコンポーネントの中の Authenticator コンポーネントは、、最小限の実装でアプリケーションに完全な認証フローを追加します。 Amplify Libraries を設定した後、以下のように数行のコードで React アプリケーションを統合することができます。

import { Amplify } from 'aws-amplify';

import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

import awsExports from './aws-exports';
Amplify.configure(awsExports);

export default function App() {
  return (
    <Authenticator>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

3. ファイルストレージ

Next.js はファイルベースのルーティングは提供しますが、クラウドベースのファイルストレージは提供しません。Amplify Storage では、画像、動画、音声などのユーザーファイルを S3 バケットにアップロードし、管理することができます。これにより、Next.js アプリからユーザーファイルのアップロード、ブログ記事の画像の保存、ポッドキャストや動画のホスティングなどの機能が利用できます。Amplify Storage は、大容量メディアファイル(PDF、音楽、動画、高解像度画像)などのマルチテラバイトファイルの Amazon S3 へのアップロードをサポートし、Amplify Libraries が署名付きアップロード URL とダウンロード URL の生成を行うため、Next.js アプリが S3 から直接ファイルをアップロードしたりフェッチすることができます。 AWS Amplify で Next.js 13 アプリにストレージを追加するためのチュートリアルについては「Add storage to a Next.js 13 app with AWS Amplify」を参照して下さい。

さらに、Amplify UIStorage Managerコンポーネントは、クラウドに接続された UI コンポーネントで、ユーザーがAmazon S3 に直接ファイルをアップロードして管理できるようにします。 Storage Manager を使用するための詳細は、AWS Front-End Web & Mobile ブログ の「Announcing the Amplify UI StorageManager Component」と、AWS Amplify Studio の「Announcing Storage Manager and Relationship Support for Form Builder」を確認して下さい。

4. テスト

AWS Amplify は一般的なエンドツーエンドのテストフレームワークである Cypress とシームレスに統合されていており、Web アプリケーションの自動テストを可能にします。Amplify Hosting は、Amplify アプリのテストフェーズでエンドツーエンドの Cypress テストを追加し、コードを本番にプッシュする前にリグレッションをキャッチするように設定することができます。

Amplify Hosting での Cypress の実装に関する詳細は、AWS Front-End Web & Mobile ブログの「Automate Testing with Authentication using AWS Amplify and Cypress」を確認して下さい。

5. ホスティング

Next.js は、SSG と SSR の 2 種類のレンダリングを提供しています。

SSG は、ビルド時に静的な HTML ファイルとしてページをレンダリングし、リクエスト時にそれを提供します。これは、更新頻度の低いページに適しており、パフォーマンスの向上、SEO、クライアントサイドのキャッシュなどの利点があります。

SSR は、リクエスト時にサーバー上でページをレンダリングし、レンダリングされた HTML をクライアントに送信します。これは、更新頻度が高いページや外部データソースへのアクセスが必要なページに適しており、サーバー上でデータをレンダリングし、最初の HTML レスポンスで送信できるなどの利点があります。

Next.js では、ページごとにどのレンダリングモードにするかを選択することができます。 例えば、マーケティングページでは SSG のみ、データベースに問い合わせる商品ページでは SSR のみ、ブログ記事では SSG、最近の投稿を一覧表示するブログホームページでは SSR といった具合です。

また、Next.js では、SSG を使用するページに対して、ISR と再バリデーションを提供しています。これにより、ビルド時にページを静的に生成し、ビルド後に再検証してインクリメンタルに再生成することができます。そのため、初期ロード時間が速いにもかかわらず、時間の経過とともにページを更新できるメリットがあります。

Next.js はハイブリッドレンダリングアプローチも提供しており、ビルド時に一部のデータを静的に生成しますが、リクエスト時にサーバーで追加のデータをフェッチします。つまり、ページの一部のデータは SSGで 、他の部分は SSRで表示されるのです。

Amplify Hosting は、ビジネスに合わせて拡張できる、高速で安全かつ信頼性の高い静的およびサーバーサイドレンダリングアプリのためのフルマネージド CI/CD およびホスティングサービスで、これらのレンダリング戦略のすべてに対応する Next.js アプリケーションの展開をサポートしています。 詳細は AWS Front-End Web & Mobile ブログの「Deploy a Next.js 13 app with authentication to AWS Amplify」「Build a Product Roadmap with Next.js and Amplify」「 Add storage to a Next.js 13 app with AWS Amplify」を確認して下さい。

本記事は、「5 Next.js features that are better with AWS Amplify」を翻訳したものです。翻訳はソリューションアーキテクトの稲田大陸が担当しました。