クイックスタート
前提条件
始める前に、以下がインストールされていることを確認してください:
- Node.js v18.17 以降
- npm v9 以降
- git v2.14.1 以降
- AWS アカウントの作成も必要です。AWS Amplify は AWS 無料利用枠の一部であることに注意してください。
- Amplify で使用するための AWS アカウントの設定 手順。
- 安定版の Flutter。
Flutter をインストールしたら、以下のコマンドを使用して新しい Flutter プロジェクトを作成できます:
flutter create my_amplify_appバックエンドの作成
AWS Amplify を始める最も簡単な方法は、create-amplify コマンドを使用して npm 経由で行うことです。ベースプロジェクトディレクトリから実行できます。まず、以下のコマンドでベースプロジェクトディレクトリに移動します:
cd my_amplify_appその後、以下を実行して Amplify プロジェクトを作成します:
npm create amplify@latest -yこのコマンドを実行すると、現在のプロジェクトに Amplify バックエンドファイルが以下のファイル構成でscaffold されます:
├── amplify/│ ├── auth/│ │ └── resource.ts│ ├── data/│ │ └── resource.ts│ ├── backend.ts│ └── package.json├── node_modules/├── .gitignore├── package-lock.json├── package.json└── tsconfig.jsonバックエンドをデプロイするには、Amplify の開発者ごとのクラウドサンドボックスを使用します。この機能はチームの各開発者に個別のバックエンド環境を提供し、ローカル開発とテストに最適です。サンドボックス環境でアプリケーションを実行するには、以下のコマンドを実行します:
npx ampx sandbox --outputs-format dart --outputs-out-dir lib認証の追加
初期のscaffoldには、amplify/auth/resource.ts ファイルに事前設定済みの認証バックエンドがすでに定義されています。メールアドレスとパスワードによるログインをサポートするように設定されていますが、Google、Amazon、Sign In With Apple、Facebook など、さまざまなログインメカニズムをサポートするように拡張できます。
ログイン体験を素早く起動する最も簡単な方法は、Amplify UI ライブラリで利用可能な Authenticator UI コンポーネントを使用することです。
Authenticator を使用するには、プロジェクトに以下の依存関係を追加する必要があります:
dependencies: amplify_flutter: ^2.0.0 amplify_auth_cognito: ^2.0.0 amplify_authenticator: ^2.0.0以下を追加します:
amplify_flutterでアプリケーションを Amplify リソースに接続します。amplify_auth_cognitoでアプリケーションを Amplify Cognito リソースに接続します。amplify_authenticatorで Amplify UI コンポーネントを使用します。
依存関係を追加したら、以下のコマンドを実行して依存関係をインストールします:
flutter pub get最後に、Amplify UI コンポーネントを使用するように main.dart ファイルを更新します:
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';import 'package:amplify_authenticator/amplify_authenticator.dart';import 'package:amplify_flutter/amplify_flutter.dart';import 'package:flutter/material.dart';
import 'amplify_outputs.dart';
Future<void> main() async { try { WidgetsFlutterBinding.ensureInitialized(); await _configureAmplify(); runApp(const MyApp()); } on AmplifyException catch (e) { runApp(Text("Error configuring Amplify: ${e.message}")); }}
Future<void> _configureAmplify() async { try { await Amplify.addPlugin(AmplifyAuthCognito()); await Amplify.configure(amplifyConfig); safePrint('Successfully configured'); } on Exception catch (e) { safePrint('Error configuring Amplify: $e'); }}
class MyApp extends StatelessWidget { const MyApp({super.key}); Widget build(BuildContext context) { return Authenticator( child: MaterialApp( builder: Authenticator.builder(), home: const Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SignOutButton(), Text('TODO Application'), ], ), ), ), ), ); }}Authenticator コンポーネントは認証バックエンドの設定を自動検出し、認証バックエンドの認証フローに基づいて正しい UI 状態をレンダリングします。
ローカル環境でアプリケーションを再度実行してみましょう。ログイン体験が表示されるはずです。
データの追加
初期のscaffoldには、amplify/data/resource.ts ファイルに事前設定済みのデータバックエンドがすでに定義されています。デフォルトの例では、content フィールドを持つ Todo モデルが作成されます。
以下を追加するように変更しましょう:
- ブール型の
isDoneフィールド。 - Auth リソースを通じて認証されたオーナーが自分のレコードを「作成」、「読み取り」、「更新」、「削除」できる認可ルール。
defaultAuthorizationModeを更新して、ユーザー認証トークンで API リクエストに署名します。
import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
const schema = a.schema({ Todo: a .model({ content: a.string(), isDone: a.boolean(), }) .authorization(allow => [allow.owner()]),});
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({ schema, authorizationModes: { defaultAuthorizationMode: "userPool", },});次に、To-do アイテムを作成、一覧表示、削除するための UI を実装しましょう。
Amplify はバックエンド API と対話するためのコードを自動的に生成できます。ターミナルでコマンドを実行して、lib/models 以下に Data スキーマから dart モデルクラスを生成します:
npx ampx generate graphql-client-code --format modelgen --model-target dart --out lib/models完了したら、プロジェクトに API 依存関係を追加します。amplify_api を追加してアプリケーションを Amplify API に接続します。
dependencies: amplify_api: ^2.0.0依存関係を追加したら、main.dart ファイルの _configureAmplify メソッドを更新して Amplify API を使用するようにします:
Future<void> _configureAmplify() async { try { await Amplify.addPlugins( [ AmplifyAuthCognito(), AmplifyAPI( options: APIPluginOptions( modelProvider: ModelProvider.instance, ), ), ], ); await Amplify.configure(amplifyConfig); safePrint('Successfully configured'); } on Exception catch (e) { safePrint('Error configuring Amplify: $e'); }}次に TodoScreen という新しいウィジェットを作成し、main.dart ファイルの末尾に以下のコードを追加します:
class TodoScreen extends StatefulWidget { const TodoScreen({super.key});
State<TodoScreen> createState() => _TodoScreenState();}
class _TodoScreenState extends State<TodoScreen> { Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton.extended( label: const Text('Add Random Todo'), onPressed: () async { final newTodo = Todo( id: uuid(), content: "Random Todo ${DateTime.now().toIso8601String()}", isDone: false, ); final request = ModelMutations.create(newTodo); final response = await Amplify.API.mutate(request: request).response; if (response.hasErrors) { safePrint('Creating Todo failed.'); } else { safePrint('Creating Todo successful.'); } }, ), body: const Placeholder(), ); }}これにより、ユーザーがフローティングアクションボタンをクリックするたびにランダムな Todo が作成されます。ModelMutations.create メソッドを使用して新しい Todo を作成していることがわかります。
main.dart ファイルの MyApp ウィジェットを以下のように更新します:
class MyApp extends StatelessWidget { const MyApp({super.key}); Widget build(BuildContext context) { return Authenticator( child: MaterialApp( builder: Authenticator.builder(), home: const SafeArea( child: Scaffold( body: Column( children: [ SignOutButton(), Expanded(child: TodoScreen()), ], ), ), ), ), ); }}次に _TodoScreenState に _todos リストを追加して API からの結果を追加し、更新関数を呼び出します:
List<Todo> _todos = [];
void initState() { super.initState(); _refreshTodos();}そして _refreshTodos という新しい関数を作成します:
Future<void> _refreshTodos() async { try { final request = ModelQueries.list(Todo.classType); final response = await Amplify.API.query(request: request).response;
final todos = response.data?.items; if (response.hasErrors) { safePrint('errors: ${response.errors}'); return; } setState(() { _todos = todos!.whereType<Todo>().toList(); }); } on ApiException catch (e) { safePrint('Query failed: $e'); }}build 関数を以下のように更新します:
Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton.extended( label: const Text('Add Random Todo'), onPressed: () async { final newTodo = Todo( id: uuid(), content: "Random Todo ${DateTime.now().toIso8601String()}", isDone: false, ); final request = ModelMutations.create(newTodo); final response = await Amplify.API.mutate(request: request).response; if (response.hasErrors) { safePrint('Creating Todo failed.'); } else { safePrint('Creating Todo successful.'); } _refreshTodos(); }, ), body: _todos.isEmpty == true ? const Center( child: Text( "The list is empty.\nAdd some items by clicking the floating action button.", textAlign: TextAlign.center, ), ) : ListView.builder( itemCount: _todos.length, itemBuilder: (context, index) { final todo = _todos[index]; return Dismissible( key: UniqueKey(), confirmDismiss: (direction) async { return false; }, child: CheckboxListTile.adaptive( value: todo.isDone, title: Text(todo.content!), onChanged: (isChecked) async {}, ), ); }, ), );}次に更新と削除機能を追加しましょう。
更新については、CheckboxListTile.adaptive ウィジェットの onChanged メソッドに以下のコードを追加します:
final request = ModelMutations.update( todo.copyWith(isDone: isChecked!),);final response = await Amplify.API.mutate(request: request).response;if (response.hasErrors) { safePrint('Updating Todo failed. ${response.errors}');} else { safePrint('Updating Todo successful.'); await _refreshTodos();}これにより、ModelMutations.update メソッドを呼び出して、todo アイテムのコピー/更新バージョンで Todo を更新します。これでチェックボックスも更新されます。
削除機能については、Dismissible ウィジェットの confirmDismiss メソッドに以下のコードを追加します:
if (direction == DismissDirection.endToStart) { final request = ModelMutations.delete(todo); final response = await Amplify.API.mutate(request: request).response; if (response.hasErrors) { safePrint('Updating Todo failed. ${response.errors}'); } else { safePrint('Updating Todo successful.'); await _refreshTodos(); return true; }}return false;これにより、ユーザーがアイテムを右から左にスワイプすると Todo アイテムが削除されます。アプリケーションを実行すると、以下のフローが表示されるはずです。
プロジェクトのクリーンアップのためにサンドボックス環境を終了できます。
クラウドへの変更の公開
クラウドへの変更の公開にはリモート git リポジトリが必要です。Amplify はフルスタックブランチデプロイメントを提供しており、フィーチャーブランチからインフラストラクチャとアプリケーションコードの変更を自動的にデプロイできます。詳細については、フルスタックブランチデプロイメントガイドをご覧ください。
🥳 成功
以上です!AWS Amplify でフルスタックアプリの構築に成功しました。Amplify の使い方についてさらに詳しく学びたい場合は、Amplify の仕組みの概念ガイドをご覧ください。