[アップデート] AWS Amplify で管理する Lambda 関数から GraphQL クライアントやクエリを使わずに Amplify 上で定義した Data スキーマを操作できるようになりました
いわさです。
今朝アナウンスがありましたが、Amplify の Functions 機能で Lambda 関数をデプロイした場合に、Lambda 関数上で Amplify Data を操作するのが簡単になります。
Amplify Data コンポーネントは実体としては AppSync を使った GraphQL スキーマです。
これまで、これを操作するためには GraphQL クライアントの操作が避けられませんでした。
先日も以下のような記事を作成したのですが、生 GraphQL クエリを書く部分がちょっと面倒で、Amplify を使うのであればうまくやってほしいなと思っていました。
今回のアップデートはまさに上記を解決するアップデートで、Function 上で Amplify のデータスキーマクライアントを生成し、フロントエンドと同じ要領でデータにアクセスできるようになります。
アップグレード
事前にお使いの Amplify バージョンを確認し更新しておきましょう。
% npx npm-check-updates -i '/@?aws-amplify/' && npm update
Upgrading /Users/iwasa.takahito/src/hogehoge/package.json
[====================] 4/4 100%
? Choose which packages to update ›
↑/↓: Select a package
Space: Toggle selection
a: Toggle all
Enter: Upgrade
❯ ◉ @aws-amplify/backend ^1.2.1 → ^1.14.0
◉ @aws-amplify/backend-cli ^1.2.5 → ^1.4.8
◉ @aws-amplify/ui-react ^6.2.2 → ^6.9.1
◉ aws-amplify ^6.6.0 → ^6.12.2
今回の前提になるのはおそらくgetAmplifyDataClientConfig
なので、以下の@aws-amplify/[email protected]
以上が必要です。
関数の実装
流れとしてはデータスキーマへの操作権限を関数に与えて関数側でスキーマクライアントを生成します。
権限の付与にはいつものようにauthorization
を使うのですが、今回の機能はスキーマ単位で付与が必要でモデル単位での付与は出来ません。そこだけ注意しましょう。
import { type ClientSchema, a, defineData } from '@aws-amplify/backend';
import { functionWithDataAccess } from '../functions/hoge0129-dataaccess/resource';
:
const schema = a.schema({
Progress: a
.model({
team_id: a.string().required(),
acl_disabled: a.boolean(),
hosting_disabled: a.boolean(),
oac_attached: a.boolean(),
bucketpolicy_fixed: a.boolean(),
versioning_enabled: a.boolean(),
})
.identifier(['team_id'])
.authorization((allow) => [
allow.ownerDefinedIn("team_id").identityClaim("custom:team_id"),
allow.publicApiKey()
]),
:
})
.authorization(allow => [
allow.resource(functionWithDataAccess).to(['query', 'listen'])
]);
:
関数リソースの定義は普段どおりで大丈夫です。
import { defineFunction } from '@aws-amplify/backend';
export const functionWithDataAccess = defineFunction({
name: 'hoge0129-dataaccess',
});
関数ハンドラーですが、getAmplifyDataClientConfig
で構成を読み込んで、Amplify.configure
後にスキーマクライアントを生成しています。
あとはフロントエンドと同じ感じでデータにアクセスできます。
import type { Handler } from 'aws-lambda';
import type { Schema } from '../../data/resource';
import { Amplify } from 'aws-amplify';
import { generateClient } from 'aws-amplify/data';
import { getAmplifyDataClientConfig } from '@aws-amplify/backend/function/runtime';
import { env } from '$amplify/env/hoge0129-dataaccess';
const { resourceConfig, libraryOptions } = await getAmplifyDataClientConfig(env);
Amplify.configure(resourceConfig, libraryOptions);
const client = generateClient<Schema>();
export const handler: Handler = async (event) => {
const { data: ScoreActivities } = await client.models.ScoreActivities.list();
console.log(ScoreActivities);
return event;
};
また、関数のデプロイ自体も必要なのでバックエンドリソースとして定義するのを忘れないようにしましょう。
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { preTokenGenerationV2 } from './auth/pre-token-generation-v2/resource';
import { functionWithDataAccess } from './functions/hoge0129-dataaccess/resource';
import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { EventSourceMapping, StartingPosition } from 'aws-cdk-lib/aws-lambda';
import { NodejsFunction} from 'aws-cdk-lib/aws-lambda-nodejs';
import * as url from 'node:url';
const backend = defineBackend({
auth,
data,
preTokenGenerationV2,
functionWithDataAccess,
});
:
実行
実行してみます。
今回は ScoreActivities モデルの一覧を list で取得してログ出力する簡単な関数を実装しています。
データマネージャーから ScoreActivities へデータを作成します。
関数をテスト実行してみます。
ログを見てみるとアイテムの内容が出力されていますね。無事アクセスすることが出来ています。
さいごに
本日は AWS Amplify で管理する Lambda 関数から GraphQL クライアントやクエリを使わずに Amplify 上で定義した Data スキーマを操作できるようになったので試してみました。
これは素晴らしいアップデートだと思います。
せっかく Amplify で色々抽象化してくれているのに Lambda の時だけ GraphQL クライアントの実装が必要だったので悩ましい方も多かったのではないでしょうか。
Amplify + Lambda が非常に使いやすくなると思いますので、活用していきたいです。