Open9
Amplify Studio - DataStoreによるシンプルなデータアクセス方法
Ampify Studio で collection ui component を開発すると、自動的にDBからfetchしてくれている。
そのソースをたどるとDataStore APIで取得しているとのこと。
内部的にはGraphQL APIだが、DataStore APIを利用したほうが楽そうなので使い方をまとめる。
参考
API
前提
Contest modelをAmplify Studioで登録済
注意点
オフライン時でも一定動作し、後で同期可能
WEBアプリであればオフライン時はすぐエラーにすべきか?アプリによるかもしれない
全件取得
const query = async () => {
const contests = await DataStore.query(Contest);
};
ID指定取得
const query = async () => {
const contest = await DataStore.query(
Contest,
"3e292085-4769-4867-981a-0efadb0ff5f4"
);
};
取得結果
{
"id": "3e292085-4769-4867-981a-0efadb0ff5f4",
"title": "abアセアンフォトコンテスト 2023",
"intro": "アセアン諸国の魅力的な場面を撮影した写真を募集します。撮影時期は問いません。これまでにアセアン諸国を訪ねた時のお気に入りの写真やとっておきの写真をご応募ください。 自宅等で作ったアセアン料理など、日本国内で撮影したアセアンを感じることができる写真も応募できます。 応募作品の中から入賞作品を含む50点程度を2023年10月17日から30日まで、堺市役所 高層館 1階 エントランスホールにて展示します。",
"host": "堺・アセアン交流促進委員会",
"postStart": "2023-07-01",
"postEnd": "2023-08-04",
"prize": "●最優秀賞(1点) 堺ゆかりの品(刃物、お香、和晒し製品、ジャム等〈総額3万円相当〉)、賞状 ●優秀賞(2点) 堺ゆかりの品(ペティナイフ、和晒し製品、ジャム等〈総額1万円相当〉)、賞状 ●優良賞(7点) 堺ゆかりの品(爪切り、お香、ジャム等〈総額3000円相当〉)、賞状 ※賞の内容は変更の場合あり",
"howToPost": "公式ホームページの応募フォームより ※「堺市電子申請システム」への利用者登録が必要",
"howToPublish": null,
"attention": null,
"note": null,
"deleteFlg": false,
"createdAt": "2023-08-03T00:30:35.453Z",
"updatedAt": "2023-08-03T01:03:39.958Z",
"_version": 3,
"_lastChangedAt": 1691024620000,
"_deleted": null
}
検索結果のcollectionへの反映例
return (
<Collection
type="list"
direction="column"
justifyContent="left"
items={items || []}
{...getOverrideProps(overrides, "ContestCard1Collection")}
{...rest}
>
{(item, index) => (
<ContestCard1
contest={item}
key={item.id}
{...(overrideItems && overrideItems({ item, index }))}
></ContestCard1>
)}
</Collection>
);
create
const create = async () => {
const result = await DataStore.save(
new Contest({
title: `画面から作成したコンテスト ${Date.now()}`,
})
);
console.log("create result", result);
};
console log
{
"title": "画面から作成したコンテスト 1691025307027",
"id": "0e7f1000-e60e-40bd-9765-6efb3416c913",
"intro": null,
"host": null,
"postStart": null,
"postEnd": null,
"prize": null,
"howToPost": null,
"howToPublish": null,
"attention": null,
"note": null,
"deleteFlg": null,
"createdAt": null,
"updatedAt": null
}
絞り込み条件を指定してquery
const query = async () => {
const contestAnd = await DataStore.query(Contest, (c) =>
c.and((c) => [c.title.contains("画面"), c.intro.eq(null)])
);
console.log(
"3. filter contest c.title.contains('画面') and c.intro.eq('')",
contestAnd
);
};
このときのgraphql
{
"query": "query operation($limit: Int, $nextToken: String, $lastSync: AWSTimestamp, $filter: ModelContestFilterInput) {\n syncContests(\n limit: $limit\n nextToken: $nextToken\n lastSync: $lastSync\n filter: $filter\n ) {\n items {\n id\n title\n intro\n host\n postStart\n postEnd\n prize\n howToPost\n howToPublish\n attention\n note\n deleteFlg\n createdAt\n updatedAt\n _version\n _lastChangedAt\n _deleted\n }\n nextToken\n startedAt\n }\n}\n",
"variables": {
"limit": 1000,
"nextToken": null,
"lastSync": 1691026076859,
"filter": null
}
}
・差分だけ取得している
・graphql (DB)でfilterしているわけではないので注意
id指定1件検索
const original = await DataStore.query(Post, id);
update
const saveResult = await DataStore.save(Post.copyOf(srcObject, updated => {
Object.assign(updated, dstObject); // 全フィールドをコピーする場合
// または
updated.name = 'hoge' // 特定フィールドを設定する場合
}))
Objectを利用して削除
const toDelete = await DataStore.query(Post, '1234567');
if (toDelete) {
DataStore.delete(toDelete);
}
削除時に条件を指定
const toDelete = await DataStore.query(Post, '123');
if (toDelete) {
DataStore.delete(toDelete, (post) => post.status.eq(PostStatus.INACTIVE));
}