NTT東日本の中村です。
昨年発表されたAmplify Gen2(プレビュー)ですが、日々機能が少しづつ追加されており、完成度が高まってきました。 前回の記事で作成したNextJSのWebアプリケーションを使い、form generate(フォームの生成機能)を試してみました。
Amplify Gen2のform generateの概要
定義されたデータモデルを元に、データ作成・データ更新の機能を生成する機能です。
データモデルが定義されると、例えば管理画面を設けて、そのデータベースへCRUD(Create、Read、Update、Delete)操作を行いたいようなケースが存在します。通常はその画面の設計・開発が必要になりますが、フォームの生成機能により、画面設計のコードが自動生成され、開発の手間を減らすことができます。 俗にScaffoldと呼ばれる機能で、pythonで言うDjangoや、PHPではCakePHPなどでも使える機能です。
Amplify Gen2のgenerate formはCRUDの中から、Create、UpdateのReactコンポーネントを提供しているようです。
個人的に、Amplify Gen2の目玉機能は、SandBoxによる開発者個別のAWSリソースを生成できることと、このform generateになるのではないかと感じています。 まだドキュメントに詳しい内容が無く、実際に挙動を確認してみました。
フォームを生成してみた
コマンドもシンプルです。
Stack、もしくはAmplify ProjectのBranchを指定すると、コードを生成してくれます。
モデルの絞り込み、出力先ディレクトリの設定が出来るくらいで、後はおまけです。
amplify generate forms
Generates UI forms
Stack identifier
--stack A stack name that contains an Amplify backend [string]
Project identifier
--app-id The Amplify App ID of the project [string]
--branch A git branch of the Amplify project [string]
Form Generation
--out-dir A path to directory where generated forms are written.
--models Model name to generate [array]
Options:
--debug Print debug logs to the console [boolean] [default: false]
--help Show help [boolean]
--profile An AWS profile name. [string]
前回作成したDataのモデルで作成します。
チュートリアルがベースですが、PKがtag、SKがcreateDateの複合キーに変更しているので
複合キーでの作成・更新に対応できるかどうかがポイントになります。
amplify/data/resource.ts
const schema = a.schema({
Todo: a
.model({
tag: a.string().required(),
content: a.string(),
done: a.boolean(),
createDate: a.string().required(),
priority: a.enum(["low", "medium", "high"]),
})
.identifier(["tag", "createDate"]) //複合キーにカスタムしている
.authorization([a.allow.owner()]),
生成
では、フォームを生成していきます。
今回は事前にSandBoxを作成し、sandBoxのcloudFormationStackをパラメータに指定します。
npx amplify generate forms --stack amplify-nextamplifygen2-nakamura-sandbox-6943a9e2ce
プロジェクトルートのui-componentsフォルダに、Create,Updateのコンポーネントが生成されました。
型定義ファイルはありますが、jsxで出力されていますね。
graphqlフォルダはgraphqlクエリがあります。今回使わないqueriesとsubscriptionsも格納されています。
create
何も考えず、作成されたコンポーネントを組み込んでみました。
app/create/page.tsx
import TodoCreateForm from "@/ui-components/TodoCreateForm";
export default function CreatePage() {
return (
<div style={{ backgroundColor: "white" }}>
<TodoCreateForm />
</div>
);
}
表示されました。項目を入力して、登録してみます。
あっさりとデータが追加され、表示されました。
update
生成されたコンポーネントのロジックを確認してみました。
更新は、更新対象となるレコードのキーか、レコードの値を直接渡す必要があります。
ui-components/TodoUpdateForm.jsx
React.useEffect(() => {
const queryData = async () => {
const record = idProp
? (
await client.graphql({
query: getTodo.replaceAll("__typename", ""),
variables: { ...idProp },
})
)?.data?.getTodo
: todoModelProp;
setTodoRecord(record);
};
queryData();
}, [idProp, todoModelProp]);
PKがtag、SKがcreateDateの複合キーになっているので、コンポーネントに複合キーの値を渡す必要があります。 リスト表示部分に更新ボタンを追加しました。
app/page.tsx
<ul>
{rangeTodoList!.map((rangeTodo) => (
<li key={rangeTodo!.tag + rangeTodo!.createDate}>
{rangeTodo!.createDate} : {rangeTodo!.content}
<Link
style={{
border: "1px solid tomato",
}}
href={`/update?tag=${rangeTodo!.tag}&createDate=${
rangeTodo!.createDate
}`}
>
更新
</Link>
</li>
))}
</ul>
更新対象のボタンを押すと、更新画面に遷移します。
対象のレコードが表示されています。 項目を書き換えて、送信を押します。
一覧画面に戻ると、項目が更新されていました。
まとめ
Amplify Gen2のform generateを使用すると、データの作成、更新を行うフォームが簡単に生成できます。
CRUD機能のような「毎回作らなければいけない機能」の工数を減らして、本来実装するべきビジネスロジックに集中できるというのは、Amplifyの変わらないメリットだと思います。