この記事は株式会社LabBase テックカレンダー Advent Calendar 2022 21日目の記事です。
毎年恒例
今年もAWS Amplifyのさまざまな機能拡張が行われた中で、今回はDataStoreを触ってみようかと思います。
AWS Amplify DataStoreとは
オフラインとオンラインのシナリオで追加のコードを書かずに共有・分散データを活用するプログラミングモデルを提供し、分散したクロスユーザーデータをローカルだけのデータと同じように簡単に扱えるようにします。(AmplifyDocsより)
つまりオフラインでもデバイス上にデータを保存することができ、オンラインになったときにはAppSyncとデータ同期をとってくれる優れものです。
新機能
今回はこちらの機能が増えました。詳しくはこちらをご覧ください.サンプルのリポジトリもあるので今回はそれを動かしてみます。
遅延ロード
スキーマ定義で hasOne, hasMany, belongsTo, manyToManyでリレーションされているデータを非同期に取得できるようになりました。
サンプルのスキーマ定義はこんな感じ
type Post @model {
title: String!
content: String!
comments: [Comment] @hasMany
}
type Comment @model {
content: String!
replies: [Reply] @hasMany
post: Post @belongsTo
}
type Reply @model {
content: String!
comment: Comment @belongsTo
}
このデータを非同期に取得しようとすると
const [posts, setPosts] = useState([]);//ここにDataStoreのオブジェクトが入る
~~~
for await (const post of posts) {
output += `${post.title}\n\n`;
output += `${post.content}\n\n`;
output += `Comments:\n`;
for await (const comment of post.comments) {
output += `- ${comment.content} @ ${comment.createdAt}\n`;
for await (const reply of comment.replies) {
output += ` - ${reply.content} @ ${reply.createdAt}\n`;
// Using `.toArray()` function
const replies = await comment.replies.toArray();
output += replies
.map((reply) => ` - ${reply.content} @ ${reply.createdAt}\n`)
.join("");
}
}
output += `-------\n`;
}
await
は当然として、toArray()
というメソッドで中身を非同期で取れるようになります。
入れ子構造のフィルター機能
入れ子になっている内部データを取得する際にフィルターをかけて取得できることができます。
useEffect(() => {
let sub;
if (filter) {
sub = DataStore.observeQuery(Post, (p) =>
p.comments.replies.content.contains(filter) //ここではfilterに文字列は入る想定
).subscribe((snapshot) => {
// ^ see new type improvements here
setPosts(snapshot.items);
});
} else {
sub = DataStore.observeQuery(Post).subscribe((snapshot) => {
setPosts(snapshot.items);
});
}
return () => sub.unsubscribe();
}, [filter]);
数千件データを入れてみて動かしてみましたが結構高速に動いていました。数万は流石に怖いので試せてませんが汗
おわり
毎年Ampfliyは進化していていいですね。今年は私自身はAmplifyをあまり触る機会は少なく、今後仕事ではあまり触りそうにないのですが、プライベートでちょこちょこ触っていこうと思います。
全然関係ないですが前回の私の記事も是非読んでみてください。
明日は栗原さんです。ご期待ください。