Introduce Amplify Flutter DataStore Extension

December 06, 2023

この記事は AWS Amplify と AWS× フロントエンド #AWSAmplifyJP Advent Calendar 2023AWS Community Builders Advent Calendar 2023 の 6 日目の記事です。

最近、Amplify & Flutter でモバイルアプリ開発をしています。 Amplify DataStore を使っているのですが、Amplify DataStore ってもう少し使いやすい API があるといいなと思っていました。

例えば、次のような Todo モデルを定義して、ID 指定で単一のレコードを取得する場合、

type Todo @model {
  id: ID!
  name: String!
  description: String
}

DataStore の API では以下のように書きます。

final id = "080f33bf-0362-4c7f-9dfa-de64fc231dca";
final todo = await Amplify.DataStore.query(
  Todo.classType,
  where: Todo.MODEL_IDENTIFIER.eq(TodoModelIdentifier(id: id)),
)
.then((list) => list.single);

ID 指定でレコードを 1 件取得するのにはちょっと、コード量が多いなと思います。 ID を指定しているので一意に決まるはずですが、DataStore では単一レコードを取得する API 自体がないので query メソッドで条件にあうレコードをリストで取得してから list.single のようにしてリストから単一レコードに変換が必要です。

希望としては、以下のように getTodo のようなメソッドがあると便利だなと思います。

final id = "080f33bf-0362-4c7f-9dfa-de64fc231dca";
final todo = await Amplify.DataStore.getTodo(id);

一覧画面でリストで表示して、ユーザーの選択に応じてその 1 件を詳細画面で表示するようなケースなどの詳細画面では ID 指定で取得するユースケースはよくあると思います。

そこで、こういったメソッドを生成する amplify-flutter-datastore-extension という Amplify プラグインを作成しました。

Amplify プラグインなので、以下のように npm でインストールして使います。

npm install -g amplify-flutter-datastore-extension
amplify plugin add $(npm root -g)/amplify-flutter-datastore-extension

インストールしたら、いつものように通常の Amplify DataStore のモデルコードの生成を実行するだけです。

amplify codegen models

そうするとDataStoreExtension.dartというファイルを生成します。 ファイルは、Amplify.DataStore の extension になっています。

例えば、最初の Todo モデルの場合は以下のような内容でファイルが生成されます。

import 'ModelProvider.dart';
import 'package:amplify_core/amplify_core.dart' as amplify_core;

/** This is an auto generated extension representing the Todo type in your schema. */
extension TodoExtension on amplify_core.DataStoreCategory {
  Future<Todo> getTodo(String id) {
    return query(
      Todo.classType,
      where: Todo.MODEL_IDENTIFIER.eq(TodoModelIdentifier(id: id)),
    )
    .then((list) => list.single);
  }

  Future<Todo?> getTodoOrNull(String id) {
    return query(
      Todo.classType,
      where: Todo.MODEL_IDENTIFIER.eq(TodoModelIdentifier(id: id)),
    )
    .then((list) => list.singleOrNull);
  }
}

ファイルが生成されたら、以下のような呼び出しが可能になります。

final id = "080f33bf-0362-4c7f-9dfa-de64fc231dca";
final todo = await Amplify.DataStore.getTodo(id);

コード量も減ってスッキリしたと思います。Flutter で Amplify DataStore を使っている方はぜひ利用してもらいたいと思います。Issue や GitHub スターなどフィードバックをいただけると励みになります。


Profile picture

Written by Masahiko MURAKAMI You should follow them on Twitter