Amazon Web Services ブログ

AWS Amplify、TanStack、AppSync、MongoDB Atlas を使用したオフラインキャッシング

このブログでは、AWS AmplifyAWS AppSyncMongoDB Atlas を使用して、オフラインファーストのアプリケーションと楽観的な UI を作成する方法をご紹介します。開発者は、インターネット接続を必要としないオフラインファーストアプリケーションを設計します。楽観的な UI は、サーバーからのレスポンスに依存することなく、予想されるデータの変更で UI を更新することで、オフラインファーストのアプローチをさらに発展させます。このアプローチは通常、ローカルキャッシュの仕組みを活用します。

オフラインファーストと楽観的 UI を組み合わせたアプリケーションは、ユーザーに多くの利点をもたらします。これには、ローディング画面を実装する必要性の低減、データアクセスの高速化によるパフォーマンスの向上、アプリケーションがオフラインの状態におけるデータの信頼性、コスト効率の向上が含まれます。オフライン機能を手動で実装するには相当な労力が必要ですが、このプロセスを簡素化するツールを使用することができます。

リクエストのラウンドトリップが完了する前に MongoDB Atlas の CRUD 操作の結果を UI に即座に表示し、ユーザーエクスペリエンスを向上させる、サンプルの Todo アプリケーションを提供しています。つまり、楽観的 UI を実装することで、ローディング状態やエラー状態の表示を容易にし、API 呼び出しが失敗した場合に開発者が UI 上の変更をロールバックできるようにしています。この実装では、TanStack Query を活用して、AWS Amplify と共に楽観的な UI の更新を処理します。図 1 は、UI とバックエンド間の連携を示しています。

TanStack Query は、TypeScript/JavaScript、React、Solid、Vue、Svelte、Angular 向けの非同期状態管理ライブラリです。Web アプリケーションにおけるサーバー状態のフェッチ、キャッシング、同期、更新を簡素化します。TanStack Query のキャッシングメカニズムを活用することで、ネットワーク接続がなくてもデータの可用性を確保できます。AWS Amplify が開発プロセスを効率化し、AWS AppSync が信頼性の高い GraphQL API レイヤーを提供し、MongoDB Atlas がスケーラブルなデータベースソリューションを提供します。この統合により、フルスタックアプリケーションアーキテクチャ内で TanStack Query のオフラインキャッシュを効果的に活用する方法が示されています。

Amplify TanStack Optimistic UI - Interaction Diagram

図 1. インタラクション図

このサンプルアプリケーションは、一般的な ToDo 機能を実装しており、その具体的なアーキテクチャは 図 2 に示されています。このスタックの構成は以下の通りです。

  • データベースサービスには MongoDB Atlas を使用します。
  • フルスタックアプリケーションフレームワークには AWS Amplify を使用します。
  • GraphQL API 管理には AWS AppSync を使用します。
  • サーバーレスコンピューティングには AWS Lambda Resolver を使用します。
  • ユーザー管理と認証には Amazon Cognito を使用します。

Amplify TanStack Optimistic UI - Architecture Diagram

図 2. アーキテクチャ

アプリケーションのデプロイ

アプリを AWS アカウントにデプロイするには、以下の手順に従ってください。デプロイが完了したら、ユーザーを作成し、認証を行い、Todo エントリを作成できます (図 8 を参照)。

MongoDB Atlas クラスターのセットアップ

  1. こちらのリンク先で、MongoDB Atlas クラスター、データベース、ユーザーネットワークアクセスをセットアップします
  2. ユーザーをセットアップします
    1. ユーザーを設定

GitHub リポジトリのクローン

  1. 以下のコマンドでサンプルアプリケーションをクローンします

git clone https://github.com/mongodb-partners/amplify-mongodb-tanstack-offline

AWS CLI 認証情報のセットアップ (ローカルでアプリケーションをデバッグする場合のオプション)

  1. サンドボックス環境を使用してアプリケーションをローカルでテストする場合は、一時的な AWS 認証情報をローカルに設定できます。
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_SESSION_TOKEN=

AWS Amplify に Todo アプリケーションをデプロイ

  1. AWS Amplify コンソールを開き、GitHub オプションを選択

Amplify TanStack Optimistic UI - Select Github Option

図 3. GitHub オプションの選択

2. GitHub リポジトリの設定

Amplify TanStack Optimistic UI - Configure Repository Permissions

図 4. リポジトリのアクセス許可を設定

3. GitHub リポジトリを選択し、Next をクリック

Amplify TanStack Optimistic UI - Select Repository and Branch
図 5. リポジトリとブランチの選択

4. その他のオプションはすべてデフォルトのままにして、デプロイ

Amplify TanStack Optimistic UI - Deploy Application

図 6. アプリケーションのデプロイ

環境変数の設定

デプロイが成功したら、環境変数を設定

Amplify TanStack Optimistic UI - Environment Variables
図 7. 環境変数の設定

アプリケーションの起動とテスト

提供された URL からアプリケーションを開き、テストを実施します。

Amplify TanStack Optimistic UI - Sample Todo entries
図 8. Todo エントリのサンプル

MongoDB Atlas の出力
Amplify TanStack Optimistic UI - Data in Mongo
図 9. MongoDB 内のデータ

アプリケーションの確認

アプリケーションがデプロイされたので、内部で何が起きているのか、何が設定されたのかについて説明しましょう。 Amplify の Git ベースのワークフローを活用して、継続的デプロイメントを備えたフルスタックのサーバーレス Web アプリケーションをホストしました。Amplify は、Next.js や Nuxt のようなサーバーサイドレンダリング (SSR) フレームワーク、React や Angular のようなシングルページアプリケーション (SPA) フレームワーク、Gatsby や Hugo のような静的サイトジェネレーター (SSG) など、さまざまなフレームワークをサポートしています。今回は、SPA の React ベースのアプリケーションをデプロイしました。フィーチャーブランチ、カスタムドメイン、プルリクエストのプレビュー、エンドツーエンドテスト、リダイレクト/リライトを含めることができます。Amplify Hosting は Git ベースのワークフローを提供し、デプロイ全体が完了した後にのみ更新が適用されるアトミックデプロイメントを実現します。

アプリケーションのデプロイには AWS Amplify Gen 2 を使用しました。これは TypeScript を使用したフルスタックアプリケーションの開発とデプロイを簡素化するために設計されたツールです。クラウドリソースの管理には AWS Cloud Development Kit (CDK) を活用し、スケーラビリティと使いやすさを確保しています。

最後に、アプリケーションの更新の同時実行性について理解することが重要です。私たちは、シンプルな楽観的先着順の競合解決メカニズムを実装しました。MongoDB Atlas クラスターは、受信した順序で更新を永続化します。更新が競合した場合、最後に到着した更新が以前の更新を上書きします。このメカニズムは、更新の競合が少ないアプリケーションでは有効に機能します。本番環境のニーズに合わせて、より高度なアプローチの必要性を検討することが重要です。TanStack は、さまざまな接続シナリオを処理するためのより複雑なメカニズムを提供します。デフォルトでは、TanStack Query は「オンライン」ネットワークモードを提供し、ネットワーク接続がない限りクエリとミューテーションは実行されません。クエリの実行中にオフラインになった場合、TanStack Query はリトライメカニズムも一時停止します。一時停止されたクエリは、ネットワーク接続が回復すると実行を再開します。UI を新しい値や変更された値で楽観的に更新するために、想定されるレスポンスでローカルキャッシュを更新することもできます。このアプローチは、TanStack の「オンライン」ネットワークモードと相性が良く、アプリケーションにネットワーク接続がない場合、ミューテーションは実行されずにキューに追加されますが、UI の更新にはローカルキャッシュを使用できます。下は、サンプルアプリケーションが期待されるミューテーション結果でUIを楽観的に更新する重要な例です。

const createMutation = useMutation({
  mutationFn: async (input: { content: string }) => {
  // Use the Amplify client to make the request to AppSync 
    const { data } = await amplifyClient.mutations.addTodo(input);
    return data ;
  },
  // When mutate is called:
  onMutate: async (newTodo) => {
    // Cancel any outgoing refetches 
    // so they don't overwrite our optimistic update 
    await tanstackClient.cancelQueries({ queryKey: ["listTodo"] });

    // Snapshot the previous value 
    const previousTodoList = tanstackClient.getQueryData(["listTodo"]);

    // Optimistically update to the new value 
    if (previousTodoList) {
      tanstackClient.setQueryData(["listTodo"], (old: Todo[]) => [ 
        ...old,
        newTodo,
      ]);
    }

    // Return a context object with the snapshotted value 
    return { previousTodoList };
  },
  // If the mutation fails,
  // use the context returned from onMutate to rollback 
  onError: (err, newTodo, context) => {
    console.error("Error saving record:", err, newTodo);
    if (context?.previousTodoList) {
      tanstackClient.setQueryData(["listTodo"], context.previousTodoList);
    }
  },
  // Always refetch after error or success:
  onSettled: () => {
    tanstackClient.invalidateQueries({ queryKey: ["listTodo"] });
  },
  onSuccess: () => {
    tanstackClient.invalidateQueries({ queryKey: ["listTodo"] });
  },
});

追加の競合解決戦略を実装する プルリクエストを歓迎します。

本記事は、2025 年 6 月 19 日に公開された Offline caching with AWS Amplify, TanStack, AppSync and MongoDB Atlas を翻訳したものです。翻訳は Solutions Architect の吉村が担当しました。

Dan Kiuna – Specialist Solutions Architect, AWS

Dan is a Specialist Solutions Architect at AWS AppSync. He is well experienced at leveraging AppSync’s capabilities alongside other AWS services to create high-performance, real-time, and offline-enabled solutions.

Igor Alekseev – Partner Solutions Architect, AWS

Igor works with strategic partners helping them build complex, AWS-optimized architectures. Prior joining AWS, as a Data/Solution Architect he implemented many projects in the Big Data domain. As a Data Engineer he was involved in applying AI/ML to fraud detection and office automation. Igor’s projects spanned a variety of industries including communications, finance, public safety, manufacturing, and healthcare.

Anuj Panchal – Partner Solutions Architect, Mongo DB

As a Partner Solutions Architect at MongoDB, I ideate, develop, and deploy seamless integrations between MongoDB and AWS offerings. My mission is to simplify the developer experience when working with MongoDB and AWS. LoveYourDevelopers