Amazon Web Services ブログ

DynamoDB JavaScript リゾルバのための新しい AWS AppSync モジュールと関数の紹介

AWS AppSync は、GraphQL API をクラウド上で構築、管理、ホストできるサービスです。AppSync を使用すると、GraphQL スキーマを記述し、リゾルバを使用してデータソースに接続するだけです。リゾルバは、AppSync が異なるデータソースから情報を取得するために GraphQL リクエストを変換する方法です。2022 年 11 月、AppSync は JavaScript リゾルバを導入し、開発者が AppSync ビジネスロジックを書きやすくなりました。JavaScript リゾルバの開始には、コードエディターでの型検証とオートコンプリートを提供する @aws-appsync/utils や開発中の問題を素早くキャッチして修正する @aws-appsync/eslint-plugin などの開発を簡素化するための NPM ライブラリが含まれています。

本日 (2023 年 8 月 31 日)、DynamoDB データソースと対話するための新しいモジュールと関数をリリースし、Amazon DynamoDB 用のリゾルバをさらに書きやすくしました。新しいモジュールは、put、get、delete、update、scan、sync、queryといった一般的な操作の DynamoDB リクエストを作成するのに必要なコードを簡素化します。さらに、更新時にアイテムの属性を細かく変更するための操作ヘルパーも提供します。このモジュールは、TypeScript を使用する場合に開発者がローカルで型安全なコードを記述できるようにするための型定義とともに、パブリックな @aws-appsync/utils パッケージで利用可能です。

概要

DynamoDB データソース用の新しい JavaScript モジュールは、DynamoDB のリクエストを数行のコードで簡単に表現できるようにします。例えば、DynamoDB テーブルに id を primaryKey とし、属性に key/value のペアを持つ新しい item を追加したいとします。以下のコードは ddb.put ユーティリティを使用しており、key と item を入力として DynamoDB の PutRequest を作成します。

import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
    const item = { id: util.autoId(), ...ctx.args };
    return ddb.put({ key: { id: item.id }, item });
}

export const response = (ctx) => ctx.result;

DynamoDB のデータソースから scan を使って情報を取得することもできます。例えば、テーブルにいくつかの項目を追加したので、それらの項目のリストを取得したいとします。以下のコードでは、ddb.scan ユーティリティを使用して、limit と nextToken の値を入力として、DynamoDB から返される結果をページ分割しています。

import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
    const { limit = 10, nextToken } = ctx.args;
    return ddb.scan({ limit, nextToken });
}

export const response = (ctx) => ctx.result.items;

次は、リゾルバロジックを追加した AppSync API でこれらの関数を使ってみましょう。

はじめに

DynamoDB 用の JavaScript モジュールは、AppSync コンソールで始めることができます。

  1. AppSync コンソールで、Create API を選択します。
  2. API Type はデフォルトのまま、Next を選択します。
  3. Specify API details ページで、API の名前を ToDo-API にし、Next を選択します。
  4. Specify GraphQL resources ページで、Create type backed by a DynamoDB table now を選択します。

AppSync コンソールは、新しい GraphQL タイプ、タイプに関連する操作、およびデータソースとして使用するDynamoDB テーブルの作成をサポートします。新しい JavaScript モジュールの機能を説明するために、id、owner、name、severity、dueOn のフィールドを持つ Todo タイプを作成します。

  1. モデル情報を以下の値で埋めてください。フィールドを追加するには、Add new field を選択します。モデル名には ToDo と入力します。Additional settings セクションで、Resolver runtime を AppSync JavaScript のままにします。

  1. モデルテーブルの構成セクションで、テーブル名、主キー、ソートキーを以下の値で入力し、Next を選択します。

  1. API の詳細を確認し、Create API を選択します。

ToDo-API、DynamoDB データソース、JavaScript リゾルバが自動的に作成されます。Schema ページでは、GraphQL スキーマの確認と変更、リゾルバの編集、スキーマのフィールドへの新しいリゾルバのアタッチができます。DynamoDB の新しい JavaScript モジュールを使用するために、リゾルバのロジックを更新してみましょう。

  1. Schema ページに移動します。Resolvers セクションで、Filter types... 検索バーに Mutation と入力します。
  2. createToDo(...) : ToDo フィールドに ToDoTable リゾルバを選択します。

createToDo リゾルバには、condition、key、および attributeValues を含む DynamoDB PutItemリクエストを構築するヘルパー関数が含まれています。これらの値はすべて DynamoDB が PutItem リクエストを期待するマップオブジェクトに変換されます。

function dynamodbPutRequest(params) {
    const { key, values, condition: inCondObj } = params;
    
    let condition;
    if (inCondObj) {
        condition = JSON.parse(util.transform.toDynamoDBConditionExpression(inCondObj));
        if (condition && condition.expressionValues && !Object.keys(condition.expressionValues).length) {
            delete condition.expressionValues;
        }
    }
    return {
        operation: 'PutItem',
        key: util.dynamodb.toMapValues(key),
        attributeValues: util.dynamodb.toMapValues(values),
        condition,
    }
}

DynamoDB の JavaScript モジュールを使って、このロジックをシンプルにしてみましょう。

  1. リゾルバのコードに以下の import 文を追加します。
import { put } from '@aws-appsync/utils/dynamodb';
  1. リクエストハンドラを以下のコードに置き換え(オプションで dynamodbPutRequest 関数を削除)、Save を選択します。
export function request(ctx) {
    const { id, owner, ...item } = ctx.args.input;
    const key = { id, owner };
    
    const condition = { };
    Object.keys(key).forEach(k => condition[k] = { attributeExists: false });
    
    return put({key, item, condition});
}

新しいモジュール関数を使用すると条件操作、キー、および属性値を構築するロジックを簡素化できます。これで、toMapValues ユーティリティや toDynamoDBConditionExpression ユーティリティを使用する必要がなくなりました。この機能は、putユーティリティ関数で抽象化されています。

updateToDo 操作のより複雑なリゾルバを見てみましょう。

  1. Schema ページに移動します。Resolvers セクションで、Filter types...検索バーに Mutation と入力します。
  2. updateToDo(...) : ToDo フィールドに ToDoTable リゾルバを選択します。

createToDo リゾルバと同様に、updateToDo リゾルバには、DynamoDB の UpdateItem リクエストを構築するヘルパー関数が含まれています。新しいモジュールを使って、このロジックを単純化してみましょう。

  1. リゾルバのコードに以下の import 文を追加します。
import { update, operations as ops } from '@aws-appsync/utils/dynamodb';
  1. リクエストハンドラを以下のコードに置き換えて、Save を選択します。
export function request(ctx) {
    const { id, owner, ...values } = ctx.args.input;
    const key = { id, owner };
    
    const condition = {};
    Object.keys(key).forEach(k => condition[k] = { attributeExists: true });
    
    const updateObj = {};
    Object.entries(values).forEach(([k,v]) => updateObj[k] = v ?? ops.remove());
    
    return update({ key, condition, update: updateObj });
}

DynamoDB 用の JavaScript モジュールを使用することで、operations 関数と update 関数を利用して更新式を作成するコードを簡素化することができます。ここでは、更新中に属性を削除するために、指定された属性が null かどうかをチェックし、operations.remove() を使用して削除されたものとしてマークしています。

operations ヘルパーは、更新中にアイテムの属性に対してさまざまなアクションを実行するために使用できる関数を提供します。利用可能なヘルパーは以下のとおりです。

  • add():属性をネストした複雑な構造を含む、新しい属性を追加します
  • remove():アイテムから属性を削除します
  • replace():既存の属性 (または入れ子になった属性) を更新時に置き換えます
  • increment():指定した数だけ属性をインクリメントします
  • decrement():属性を指定した数だけデクリメントします
  • append():属性の末尾に項目を追加します: 属性リストの最後に項目を追加します
  • prepend():属性リストの先頭に項目を追加します
  • updateListItem():リストの特定のインデックスの項目を更新します

operations ヘルパーを使用すると、以下のように、JavaScript リゾルバで複雑な更新操作を数行で書くことができます。

import { update, operations as ops } from '@aws-appsync/utils/dynamodb';
export function request(ctx) {
    const updateObj = {
        count: ops.increment(1),
        friends: ops.append(['John']),
        address: ops.add({ street1: '123 Main St', street2: 'Unit A', city: 'New York', zip: '10001' }),
        pets: [ops.updateListItem('rex', 2)],
    };
    const condition = { friends: { size: { lt: 5 } }, id: { attributeExists: true } };
    return update({ key: { id: 1 }, update: updateObj, condition });
}

上のコードの更新リクエストでは以下を行っています。

  • count 属性のインクリメント
  • フレンドリストに “John” をフレンドとして追加
  • アイテムに住所の追加
  • pet 属性の 3 番目のエントリの値を変更

更新は、指定されたキー (id) を持つアイテムが存在し、友達リストのサイズが 5 未満である場合にのみ許可されます。

モジュール関数の詳細については、AppSync ドキュメントを参照してください。これらの新しい関数の使用方法については、AWS AppSync examples リポジトリを参照してください。

まとめ

本記事では、AppSync リゾルバのリゾルバロジックを簡素化する DynamoDB の新しいJavaScriptモジュールについてレビューしました。さらに、AWS AppSync を簡単に使い始める方法と、新しいモジュールを使用するリゾルバの書き方についても説明しました。JavaScript のリゾルバや DynamoDB の新機能の詳細については、ドキュメントやチュートリアルを参照してください。また、使いやすいサンプルやガイドは samples リポジトリにあります。

本記事は、Introducing new AWS AppSync module and functions for DynamoDB JavaScript resolvers を翻訳したものです。翻訳はソリューションアーキテクトの稲田大陸が担当しました。