DynamoDB リゾルバーを使用したシンプルなポストアプリケーションの作成 - AWS AppSync

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

DynamoDB リゾルバーを使用したシンプルなポストアプリケーションの作成

注記

現在、主に APPSYNC_JS ランタイムとそのドキュメントをサポートしています。APPSYNC_JS ランタイムとそのガイドをここで使用することを検討してください。

このチュートリアルでは、独自の Amazon DynamoDB テーブルを に持ち込み AWS AppSync 、GraphQL に接続する方法を示しますAPI。

DynamoDB リソースをユーザーに代わって AWS AppSync プロビジョニングできます。または、必要であれば、データソースとリゾルバーを作成することで、既存のテーブルを GraphQL スキーマに接続できます。いずれの場合も、GraphQL ステートメントを使用して DynamoDB データベースへの読み取りと書き込みを行うことができ、リアルタイムデータをサブスクライブできます。

GraphQL ステートメントが DynamoDB オペレーションに変換され、レスポンスが GraphQL に変換されるように、特定の設定ステップを完了しておく必要があります。このチュートリアルでは、いくつかの実際のシナリオおよびデータアクセスパターンを使用して、その設定手順の概要を示します。

DynamoDB テーブルのセットアップ

このチュートリアルを開始するには、まず以下の手順に従って AWS リソースをプロビジョニングする必要があります。

  1. の次の AWS CloudFormation テンプレートを使用して AWS リソースをプロビジョニングしますCLI。

    aws cloudformation create-stack \ --stack-name AWSAppSyncTutorialForAmazonDynamoDB \ --template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml \ --capabilities CAPABILITY_NAMED_IAM

    または、アカウントの米国西部 2 (オレゴン) リージョンで次の AWS CloudFormation スタックを起動することもできます AWS 。

    Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

    これにより、以下の項目が作成されます。

    • データを保持するDynamoDBテーブルがAppSyncTutorial-Post呼び出されます。Post

    • AWS AppSync がPostテーブルとやり取りできるようにするIAMロールと関連付けられたIAM管理ポリシー。

  2. スタックと作成されたリソースの詳細については、次のCLIコマンドを実行します。

    aws cloudformation describe-stacks --stack-name AWSAppSyncTutorialForAmazonDynamoDB
  3. そのリソースを削除するには、次のコマンドを実行します。

    aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB

GraphQL の作成 API

API で GraphQL を作成するには AWS AppSync:

  1. にサインイン AWS Management Console し、AppSync コンソール を開きます。

    1. APIs ダッシュボード で「 の作成API」を選択します。

  2. Amazon DynamoDB ウィンドウから APIまたは をインポートする で、ゼロからビルド を選択します。

    1. 同じウィンドウの右にある [開始] を選択します。

  3. API 名前フィールドで、 の名前を API に設定しますAWSAppSyncTutorial

  4. [Create] (作成) を選択します。

AWS AppSync コンソールは、APIキー認証モードAPIを使用して新しい GraphQL を作成します。コンソールを使用して、GraphQL の残りの部分をセットアップAPIし、このチュートリアルの残りの部分に対してクエリを実行できます。

基本的な投稿の定義 API

AWS AppSync GraphQL を作成したらAPI、投稿データの基本作成、取得、削除を許可する基本スキーマを設定できます。

  1. にサインイン AWS Management Console し、AppSync コンソール を開きます。

    1. APIs ダッシュボード で、API先ほど作成した を選択します。

  2. サイドバー[スキーマ] を選択します。

    1. [スキーマ] ペインで、内容を次のコードに置き換えます。

      schema { query: Query mutation: Mutation } type Query { getPost(id: ID): Post } type Mutation { addPost( id: ID! author: String! title: String! content: String! url: String! ): Post! } type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! }
  3. [Save] を選択します。

このスキーマでは、Post 型と、Post オブジェクトを追加および取得するオペレーションを定義しています。

DynamoDB テーブル用のデータソースの設定

次に、スキーマで定義されているクエリとミューテーションを AppSyncTutorial-Post DynamoDB テーブルにリンクします。

まず、テーブルに注意 AWS AppSync する必要があります。これを行うには、 でデータソースを設定します AWS AppSync。

  1. にサインイン AWS Management Console し、AppSync コンソール を開きます。

    1. APIs ダッシュボード で、GraphQL を選択しますAPI。

    2. サイドバー[データソース] を選択します。

  2. [データソースを作成] を選択します。

    1. データソース名には、PostDynamoDBTable を入力します。

    2. [データソースタイプ] として [Amazon DynamoDB テーブル] を選択します。

    3. リージョン ではUS-WEST-2 を選択します。

    4. テーブル名 で、AppSyncTutorial-Post DynamoDB テーブルを選択します。

    5. 新しいIAMロールを作成する (推奨) か、 lambda:invokeFunction IAM 許可を持つ既存のロールを選択します。データソースのアタッチセクションで説明しているように、既存のロールには信頼ポリシーが必要です。

      以下は、 リソースでオペレーションを実行するために必要なアクセス許可を持つIAMポリシーの例です。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lambda:invokeFunction" ], "Resource": [ "arn:aws:lambda:us-west-2:123456789012:function:myFunction", "arn:aws:lambda:us-west-2:123456789012:function:myFunction:*" ] } ] }
  3. [Create] (作成) を選択します。

addPost リゾルバーの設定 (DynamoDB PutItem)

AWS AppSync が DynamoDB テーブルを認識したら、リゾルバー を定義して、個々のクエリとミューテーションにリンクできます。最初に作成するリゾルバーは addPost リゾルバーです。このリゾルバーによって、ユーザーが AppSyncTutorial-Post DynamoDB テーブルにポストを作成できるようになります。

リゾルバーには以下のコンポーネントがあります。

  • リゾルバーをアタッチする、GraphQL スキーマ内の場所。この例では、addPost 型の Mutation フィールドにリゾルバーをセットアップしています。このリゾルバーは、呼び出し元が mutation { addPost(...){...} } を呼び出したときに呼び出されます。

  • このリゾルバーで使用するデータソース。この例では、PostDynamoDBTable DynamoDB テーブルにエントリを追加できるように、前に定義した AppSyncTutorial-Post データソースを使用します。

  • リクエストマッピングテンプレート。リクエストマッピングテンプレートの目的は、発信者から受信したリクエストを受け取り、DynamoDB に対して を実行する AWS AppSync ための の手順に変換することです。

  • レスポンスマッピングテンプレート。レスポンスマッピングテンプレートの目的は、DynamoDB からのレスポンスを取り込み、それを GraphQL で想定されているものに変換し直すことです。これは、DynamoDB でのデータのシェイプが GraphQL での Post 型と異なる場合に便利です。ただし、この例では、両方のシェイプが同じであるため、データをそのまま渡します。

リゾルバーをセットアップするには、以下の手順に従います。

  1. にサインイン AWS Management Console し、AppSync コンソール を開きます。

    1. APIs ダッシュボード で、GraphQL を選択しますAPI。

    2. サイドバー[データソース] を選択します。

  2. [データソースを作成] を選択します。

    1. データソース名には、PostDynamoDBTable を入力します。

    2. [データソースタイプ] として [Amazon DynamoDB テーブル] を選択します。

    3. リージョン ではUS-WEST-2 を選択します。

    4. テーブル名 で、AppSyncTutorial-Post DynamoDB テーブルを選択します。

    5. 新しいIAMロールを作成する (推奨) か、 lambda:invokeFunction IAM 許可を持つ既存のロールを選択します。データソースのアタッチセクションで説明しているように、既存のロールには信頼ポリシーが必要です。

      以下は、 リソースでオペレーションを実行するために必要なアクセス許可を持つIAMポリシーの例です。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lambda:invokeFunction" ], "Resource": [ "arn:aws:lambda:us-west-2:123456789012:function:myFunction", "arn:aws:lambda:us-west-2:123456789012:function:myFunction:*" ] } ] }
  3. [Create] (作成) を選択します。

  4. [Schema (スキーマ)] タブを選択します。

  5. 右側のデータ型ペインで、ミューテーションタイプの addPostフィールドを検索し、「 をアタッチ」を選択します。

  6. アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。

  7. [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  8. 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "attributeValues" : { "author" : $util.dynamodb.toDynamoDBJson($context.arguments.author), "title" : $util.dynamodb.toDynamoDBJson($context.arguments.title), "content" : $util.dynamodb.toDynamoDBJson($context.arguments.content), "url" : $util.dynamodb.toDynamoDBJson($context.arguments.url), "ups" : { "N" : 1 }, "downs" : { "N" : 0 }, "version" : { "N" : 1 } } }

    注 : 「型」はすべてのキーと属性値で指定されています。例えば、author フィールドを { "S" : "${context.arguments.author}" } に設定します。S パートは、 AWS AppSync と DynamoDB に、値が文字列値になることを示します。実際の値は author 引数から入力されます。同様に、version フィールドは、型として N が使用されているため数値フィールドです。最後に、upsdowns および version フィールドの初期化も行っています。

    このチュートリアルでは、DynamoDB に挿入された新しい項目にインデックスを付ける GraphQL ID!タイプが、 という自動 ID 生成用のユーティリティを持つ client arguments. AWS AppSync comes の一部として提供されることを指定しました。$utils.autoId()これは、 の形式でも使用できます"id" : { "S" : "${$utils.autoId()}" }。 DynamoDB そのため、id: ID!addPost() のスキーマ定義から除外するだけで、自動的に挿入されます。このチュートリアルではこの手法を使用しませんが、DynamoDB テーブルに書き込む場合はこの手法を検討することをお勧めします。

    マッピングテンプレートの詳細については、「リゾルバーのマッピングテンプレートの概要」リファレンスドキュメントを参照してください。 GetItem リクエストマッピングの詳細については、GetItemリファレンスドキュメントを参照してください。型の詳細については、「型システム (リクエストマッピング)」リファレンスドキュメントを参照してください。

  9. 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)

    注 : AppSyncTutorial-Post テーブルでのデータのシェイプは GraphQL での Post 型のシェイプと厳密に一致しているため、このレスポンスマッピングテンプレートは結果をそのまま渡すだけです。また、このチュートリアルのすべての例では、これと同じレスポンスマッピングテンプレートだけを使用しているため、作成するファイルはこの 1 つだけです。

  10. [Save] を選択します。

を呼び出しAPIて投稿を追加する

リゾルバーが設定されたら、着信addPostミューテーションを DynamoDB PutItem オペレーションに変換 AWS AppSync できます。ユーザーはミューテーションを実行してテーブルに何かを入れることができるようになりました。

  • [クエリ] タブを選択します。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。

    mutation addPost { addPost( id: 123 author: "AUTHORNAME" title: "Our first post!" content: "This is our first post." url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • 新しく作成されたポストの結果が、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "addPost": { "id": "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

何が起こったのかを以下に説明します。

  • AWS AppSync はaddPostミューテーションリクエストを受信しました。

  • AWS AppSync はリクエストとリクエストマッピングテンプレートを受け取り、リクエストマッピングドキュメントを生成しました。そのドキュメントは次のようになっていました。

    { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "123" } }, "attributeValues" : { "author": { "S" : "AUTHORNAME" }, "title": { "S" : "Our first post!" }, "content": { "S" : "This is our first post." }, "url": { "S" : "https://aws.amazon.com/appsync/" }, "ups" : { "N" : 1 }, "downs" : { "N" : 0 }, "version" : { "N" : 1 } } }
  • AWS AppSync は、リクエストマッピングドキュメントを使用して DynamoDBPutItem リクエストを生成および実行しました。

  • AWS AppSync はPutItemリクエストの結果を受け取り、GraphQL タイプに変換しました。

    { "id" : "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups" : 1, "downs" : 0, "version" : 1 }
  • そのデータは、レスポンスマッピングドキュメントを介して変更されずに渡されました。

  • 新しく作成されたオブジェクトが GraphQL レスポンスで返されました。

getPost リゾルバーのセットアップ (DynamoDB GetItem)

これで、AppSyncTutorial-Post DynamoDB テーブルにデータを追加できるようになりました。次は、AppSyncTutorial-Post テーブルからデータを取得できるように、getPost クエリを設定する必要があります。そのためには、別のリゾルバーを設定します。

  • [Schema (スキーマ)] タブを選択します。

  • 右側のデータ型ペインで、クエリタイプの getPostフィールドを検索し、「 をアタッチ」を選択します。

  • アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id) } }
  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)
  • [Save] を選択します。

API を呼び出して投稿を取得する

これでリゾルバーが設定され、受信getPostクエリを DynamoDBGetItem オペレーションに変換する方法が AWS AppSync わかりました。次は、先ほど作成したポストを取得するクエリを実行します。

  • [クエリ] タブを選択します。

  • [Queries] ペインに、次の内容を貼り付けます。

    query getPost { getPost(id:123) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • DynamoDB から取得されたポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "getPost": { "id": "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

何が起こったのかを以下に説明します。

  • AWS AppSync はgetPostクエリリクエストを受信しました。

  • AWS AppSync はリクエストとリクエストマッピングテンプレートを受け取り、リクエストマッピングドキュメントを生成しました。そのドキュメントは次のようになっていました。

    { "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : { "S" : "123" } } }
  • AWS AppSync は、リクエストマッピングドキュメントを使用して DynamoDB GetItem リクエストを生成および実行しました。

  • AWS AppSync はGetItemリクエストの結果を受け取り、GraphQL タイプに変換しました。

    { "id" : "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups" : 1, "downs" : 0, "version" : 1 }
  • そのデータは、レスポンスマッピングドキュメントを介して変更されずに渡されました。

  • 取得したオブジェクトがレスポンスで返されました。

別の方法として、次の例を指定します。

query getPost { getPost(id:123) { id author title } }

getPost クエリに、idauthor および title のみが必要な場合は、DynamoDB から AWS AppSyncへの不要なデータ転送を避けるため、投影式を使用して DynamoDB テーブルから必要な属性のみを指定するようにリクエストマッピングテンプレートを変更できます。例えば、リクエストマッピングテンプレートは以下のスニペットのようになります。

{ "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id) }, "projection" : { "expression" : "#author, id, title", "expressionNames" : { "#author" : "author"} } }

updatePost Mutation を作成する (DynamoDB UpdateItem)

これで、DynamoDB 内の Post オブジェクトを作成および取得できるようになりました。次は、オブジェクトを更新できるように、新しいミューテーションを設定します。これは UpdateItem DynamoDB オペレーションを使用して行います。

  • [Schema (スキーマ)] タブを選択します。

  • [スキーマ] ペインの Mutation タイプを次のように変更して、新しい updatePost ミューテーションを追加します。

    type Mutation { updatePost( id: ID!, author: String!, title: String!, content: String!, url: String! ): Post addPost( author: String! title: String! content: String! url: String! ): Post! }
  • [Save] を選択します。

  • 右側のデータ型ペインで、ミューテーションタイプで新しく作成されたupdatePostフィールドを見つけて、アタッチ を選択します。

  • アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "SET author = :author, title = :title, content = :content, #url = :url ADD version :one", "expressionNames": { "#url" : "url" }, "expressionValues": { ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author), ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title), ":content" : $util.dynamodb.toDynamoDBJson($context.arguments.content), ":url" : $util.dynamodb.toDynamoDBJson($context.arguments.url), ":one" : { "N": 1 } } } }

    注: このリゾルバーは DynamoDB UpdateItemを使用しています。DynamoDB は PutItem オペレーションとは大きく異なります。DynamoDB では、項目全体が書き込まれるのではなく、特定の属性が更新されるようにします。これを行うには、DynamoDB の更新式を使用します。その式自体は、expression セクションの update フィールドで指定されています。その式では、authortitlecontent、url の各属性を設定し、version フィールドを増分しています。使用される値は式自体には記述されていません。この式には、名前がコロンで始まるプレースホルダーがあり、それぞれの値は expressionValues フィールドで定義されています。最後に、DynamoDB には、expression で使用できない予約語があります。例えば、url は予約語であるため、url フィールドを更新するには、名前のプレースホルダーを expressionNames フィールドで定義できます。

    UpdateItem リクエストマッピングの詳細については、UpdateItemリファレンスドキュメントを参照してください。更新式を記述する方法の詳細については、DynamoDB UpdateExpressions ドキュメント を参照してください。

  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)

API を呼び出して投稿を更新する

これでリゾルバーが設定され、着信updateミューテーションを DynamoDBUpdate オペレーションに変換する方法が AWS AppSync わかりました。ユーザーは、前のステップで書き込んだ項目を更新するミューテーションを実行できるようになりました。

  • [クエリ] タブを選択します。

  • 次のミューテーションを [Queries (クエリ)] ペインに貼り付けます。また、id 引数を、前にメモしておいた値に更新する必要があります。

    mutation updatePost { updatePost( id:"123" author: "A new author" title: "An updated author!" content: "Now with updated content!" url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • DynamoDB で更新されたポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "updatePost": { "id": "123", "author": "A new author", "title": "An updated author!", "content": "Now with updated content!", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 2 } } }

この例では、リクエストマッピングテンプレートが AWS AppSync と DynamoDB にそれらのdownsフィールドに対して何もするように要求しなかったため、 ups および フィールドは変更されませんでした。また、 version と AWS AppSync DynamoDB に 1 を フィールドに追加するように依頼したため、 versionフィールドは 1 ずつ増加しました。

updatePost リゾルバーの変更 (DynamoDB UpdateItem)

updatePost ミューテーションの手始めとしてはこれで十分ですが、次の 2 つの主な問題があります。

  • 1 つのフィールドだけを更新する場合でも、すべてのフィールドを更新する必要があります。

  • 2 人のユーザーがこのオブジェクトを変更すると、情報が失われる可能性があります。

これらの問題に対処するために、リクエストで指定された引数のみを変更し、UpdateItem オペレーションに条件を追加するように、updatePost ミューテーションを修正します。

  1. [Schema (スキーマ)] タブを選択します。

  2. [Schema (スキーマ)] ペインで Mutation 型の updatePost フィールドを変更して、authortitlecontenturl の各引数から感嘆符を除去し、id フィールドが元のままになるようにします。これにより、それらの引数が省略可能になります。また、新しい必須の expectedVersion 引数を追加します。

    type Mutation { updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String! title: String! content: String! url: String! ): Post! }
  3. [Save] を選択します。

  4. 右側のデータ型ペインで、ミューテーションタイプの updatePostフィールドを見つけます。

  5. PostDynamoDBTable を選択して既存のリゾルバーを開きます。

  6. [Configure the request mapping template (リクエストマッピングテンプレートの設定)] にあるリクエストマッピングテンプレートを次のように変更します。

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, ## Set up some space to keep track of things you're updating ** #set( $expNames = {} ) #set( $expValues = {} ) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) ## Increment "version" by 1 ** $!{expAdd.put("version", ":one")} $!{expValues.put(":one", { "N" : 1 })} ## Iterate through each argument, skipping "id" and "expectedVersion" ** #foreach( $entry in $context.arguments.entrySet() ) #if( $entry.key != "id" && $entry.key != "expectedVersion" ) #if( (!$entry.value) && ("$!{entry.value}" == "") ) ## If the argument is set to "null", then remove that attribute from the item in DynamoDB ** #set( $discard = ${expRemove.add("#${entry.key}")} ) $!{expNames.put("#${entry.key}", "$entry.key")} #else ## Otherwise set (or update) the attribute on the item in DynamoDB ** $!{expSet.put("#${entry.key}", ":${entry.key}")} $!{expNames.put("#${entry.key}", "$entry.key")} $!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })} #end #end #end ## Start building the update expression, starting with attributes you're going to SET ** #set( $expression = "" ) #if( !${expSet.isEmpty()} ) #set( $expression = "SET" ) #foreach( $entry in $expSet.entrySet() ) #set( $expression = "${expression} ${entry.key} = ${entry.value}" ) #if ( $foreach.hasNext ) #set( $expression = "${expression}," ) #end #end #end ## Continue building the update expression, adding attributes you're going to ADD ** #if( !${expAdd.isEmpty()} ) #set( $expression = "${expression} ADD" ) #foreach( $entry in $expAdd.entrySet() ) #set( $expression = "${expression} ${entry.key} ${entry.value}" ) #if ( $foreach.hasNext ) #set( $expression = "${expression}," ) #end #end #end ## Continue building the update expression, adding attributes you're going to REMOVE ** #if( !${expRemove.isEmpty()} ) #set( $expression = "${expression} REMOVE" ) #foreach( $entry in $expRemove ) #set( $expression = "${expression} ${entry}" ) #if ( $foreach.hasNext ) #set( $expression = "${expression}," ) #end #end #end ## Finally, write the update expression into the document, along with any expressionNames and expressionValues ** "update" : { "expression" : "${expression}" #if( !${expNames.isEmpty()} ) ,"expressionNames" : $utils.toJson($expNames) #end #if( !${expValues.isEmpty()} ) ,"expressionValues" : $utils.toJson($expValues) #end }, "condition" : { "expression" : "version = :expectedVersion", "expressionValues" : { ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion) } } }
  7. [Save] を選択します。

このテンプレートでは、より複雑な例を示します。マッピングテンプレートの力と柔軟性を示しています。すべての引数をループ処理し、idexpectedVersion をスキップしています。引数が何かに設定されている場合、 AWS AppSync と DynamoDB は、DynamoDB の オブジェクトでその属性を更新するように要求します。属性が null に設定されている場合、 AWS AppSync と DynamoDB はポストオブジェクトからその属性を削除するように要求します。引数が指定されていない場合、その属性は元のままになります。また、version フィールドが増分されます。

また、新しい condition セクションがあります。条件式を使用すると、オペレーションが実行される前に、DynamoDB に既にあるオブジェクトの状態に基づいてリクエストが成功するかどうかを AWS AppSync と DynamoDB に指示できます。この例では、DynamoDB に現在ある項目の version フィールドが expectedVersion 引数と厳密に一致する場合にのみ、UpdateItem リクエストが成功するように指示しています。

条件式の詳細については、「条件式」リファレンスドキュメントを参照してください。

API を呼び出して投稿を更新する

新しいリゾルバーで Post オブジェクトを更新してみましょう。

  • [クエリ] タブを選択します。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。また、id 引数を、前にメモしておいた値に更新する必要があります。

    mutation updatePost { updatePost( id:123 title: "An empty story" content: null expectedVersion: 2 ) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • DynamoDB で更新されたポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "updatePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 3 } } }

このリクエストでは、 AWS AppSync と DynamoDB に titlecontentフィールドのみを更新するように依頼しました。その他のフィールドは元のままです (増分する version フィールドは除く)。title 属性を新しい値に設定し、ポストから content 属性を削除しています。authorurlupsdowns の各フィールドは変更されません。

リクエストはまったく同じままで、このミューテーションをもう一度実行してみます。次のようなレスポンスが表示されます。

{ "data": { "updatePost": null }, "errors": [ { "path": [ "updatePost" ], "data": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 3 }, "errorType": "DynamoDB:ConditionalCheckFailedException", "locations": [ { "line": 2, "column": 3 } ], "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)" } ] }

このリクエストは、条件式が false と評価されるため失敗します。

  • このリクエストを最初に実行したときに、DynamoDB 内のこのポストの version フィールドの値は 2 であり、expectedVersion 引数と一致していました。このリクエストは成功し、DynamoDB で version フィールドが 3 に増分されました。

  • このリクエストを 2 回目に実行したときに、DynamoDB 内のこのポストの version フィールドの値は 3 であり、expectedVersion 引数と一致していませんでした。

このパターンは通常、「楽観的ロック」と呼ばれます。

AWS AppSync DynamoDB リゾルバーの特徴は、DynamoDB のポストオブジェクトの現在の値が返されることです。そのことは、GraphQL レスポンスの data セクションの errors フィールドで確認できます。アプリケーションでは、この情報を使用して、どのように続行するかを決めることができます。この例では、DynamoDB 内のオブジェクトの version フィールドが 3 に設定されていることを確認できるため、expectedVersion 引数を 3 に更新するだけで、このリクエストが再度成功するようになります。

条件チェックの失敗の処理の詳細については、マッピングテンプレートのリファレンスドキュメントの「条件式」を参照してください。

作成 upvotePost と downvotePost ミューテーション (DynamoDB UpdateItem)

Post タイプには、レコードのアップボーテとダウンボーテを有効にする upsフィールドと downsフィールドがありますが、これまでのところ、 APIではそれらに対して何もできません。ポストに賛成および反対するための、いくつかのミューテーションを追加してみましょう。

  • [Schema (スキーマ)] タブを選択します。

  • [スキーマ] ペインの Mutation タイプを変更して、新しい upvotePostdownvotePost ミューテーションを次のように追加します。

    type Mutation { upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }
  • [Save] を選択します。

  • 右側のデータ型ペインで、ミューテーションタイプで新しく作成されたupvotePostフィールドを見つけ、 のアタッチを選択します。

  • アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "ADD ups :plusOne, version :plusOne", "expressionValues" : { ":plusOne" : { "N" : 1 } } } }
  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)
  • [Save] を選択します。

  • 右側のデータ型ペインで、ミューテーション型の新しく作成された downvotePost フィールドを見つけて、[アタッチ] を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "ADD downs :plusOne, version :plusOne", "expressionValues" : { ":plusOne" : { "N" : 1 } } } }
  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)
  • [Save] を選択します。

API を呼び出して投稿をアップボットおよびダウンボットする

これで新しいリゾルバーが設定され、受信upvotePostまたはdownvoteミューテーションを DynamoDB UpdateItem オペレーションに変換する方法が AWS AppSync わかりました。これで、先ほど作成したポストに賛成または反対するミューテーションを実行できるようになりました。

  • [クエリ] タブを選択します。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。また、id 引数を、前にメモしておいた値に更新する必要があります。

    mutation votePost { upvotePost(id:123) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • そのポストが DynamoDB で更新され、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "upvotePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 0, "version": 4 } } }
  • さらに数回、[Execute query (クエリを実行)] を選択します。このクエリを実行するたびに、ups フィールドと version フィールドが 1 つずつ増加することを確認できます。

  • 次のようにクエリを変更し、downvotePost ミューテーションを呼び出します。

    mutation votePost { downvotePost(id:123) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。今度は、このクエリを実行するたびに、downs フィールドと version フィールドが 1 つずつ増加することを確認できます。

    { "data": { "downvotePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 4, "version": 12 } } }

deletePost リゾルバーのセットアップ (DynamoDB DeleteItem)

次は、ポストを削除するミューテーションを設定します。そのためには、DynamoDB の DeleteItem オペレーションを使用します。

  • [Schema (スキーマ)] タブを選択します。

  • [スキーマ] ペインの Mutation タイプを次のように変更して、新しい deletePost ミューテーションを追加します。

    type Mutation { deletePost(id: ID!, expectedVersion: Int): Post upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }

    今回は、expectedVersion フィールドを省略可能にしています。これについては、リクエストマッピングテンプレートを追加するときに説明します。

  • [Save] を選択します。

  • 右側のデータ型ペインで、ミューテーション型の新しく作成された delete フィールドを見つけて、[アタッチ] を選択します。

  • アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "DeleteItem", "key": { "id": $util.dynamodb.toDynamoDBJson($context.arguments.id) } #if( $context.arguments.containsKey("expectedVersion") ) ,"condition" : { "expression" : "attribute_not_exists(id) OR version = :expectedVersion", "expressionValues" : { ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion) } } #end }

    注 : expectedVersion 引数は省略可能な引数です。呼び出し元がリクエストで expectedVersion 引数を設定していると、項目が既に削除されている場合、または DynamoDB 内のポストの version 属性が expectedVersion と完全に一致する場合にのみ、DeleteItem リクエストが成功することを許可する条件が、テンプレートによって追加されます。この引数が省略されている場合は、DeleteItem リクエストで条件式が指定されていません。version の値や項目が DynamoDB に存在するかどうかに関係なく、成功します。

  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)

    注意: 項目を削除する場合でも、その項目がまだ削除されていなければ、削除された項目を返すことができます。

  • [Save] を選択します。

DeleteItem リクエストマッピングの詳細については、DeleteItemリファレンスドキュメントを参照してください。

API を呼び出して投稿を削除する

これでリゾルバーが設定され、着信deleteミューテーションを DynamoDBDeleteItem オペレーションに変換する方法が AWS AppSync わかりました。ユーザーはミューテーションを実行してテーブル内の何かを削除できるようになりました。

  • [クエリ] タブを選択します。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。また、id 引数を、前にメモしておいた値に更新する必要があります。

    mutation deletePost { deletePost(id:123) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • このポストが DynamoDB から削除されます。は、DynamoDB から削除された項目の値を AWS AppSync 返すことに注意してください。この値は、クエリペインの右側の結果ペインに表示されます。これは次のように表示されます。

    { "data": { "deletePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 4, "version": 12 } } }

この値は、この deletePost 呼び出しによって実際に DynamoDB から項目が削除された場合にのみ返されます。

  • [クエリを実行] を再度選択します。

  • この呼び出しは成功しますが、値は返されません。

    { "data": { "deletePost": null } }

次は、expectedValue を指定して、ポストを削除してみましょう。ただし、これまで使用してきたポストは削除したため、まず新しいポストを作成する必要があります。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。

    mutation addPost { addPost( id:123 author: "AUTHORNAME" title: "Our second post!" content: "A new post." url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • 新しく作成されたポストの結果が、クエリペインの右側にある結果ペインに表示されます。新しく作成されたオブジェクトの id を書き留めておきます。その値はすぐに必要になります。これは次のように表示されます。

    { "data": { "addPost": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

次に、expectedVersion に間違った値を入れて、ポストを削除してみましょう。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。また、id 引数を、前にメモしておいた値に更新する必要があります。

    mutation deletePost { deletePost( id:123 expectedVersion: 9999 ) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

    { "data": { "deletePost": null }, "errors": [ { "path": [ "deletePost" ], "data": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 }, "errorType": "DynamoDB:ConditionalCheckFailedException", "locations": [ { "line": 2, "column": 3 } ], "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)" } ] }

    条件式が false と評価されるため、このリクエストは失敗しました。DynamoDB でのそのポストの version の値が、expectedValue 引数で指定したものと一致していないためです。そのオブジェクトの現在の値が、GraphQL レスポンスの data セクションの errors フィールドで返されます。

  • expectedVersion を訂正して、このリクエストをもう一度試してみます。

    mutation deletePost { deletePost( id:123 expectedVersion: 1 ) { id author title content url ups downs version } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • 今回は、リクエストが成功し、DynamoDB から削除された値が返されています。

    { "data": { "deletePost": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }
  • [クエリを実行] を再度選択します。

  • この呼び出しは成功しますが、そのポストが DynamoDB で既に削除されているため、今回は値が返されません。

{ "data": { "deletePost": null } }

allPost リゾルバーのセットアップ (DynamoDB スキャン)

これまでのところ、 APIは、参照する各投稿idの がわかっている場合にのみ役立ちます。テーブル内のすべてのポストを返す新しいリゾルバーを追加してみましょう。

  • [Schema (スキーマ)] タブを選択します。

  • [スキーマ] ペインの Query タイプを次のように変更して、新しい allPost クエリを追加します。

    type Query { allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
  • 新しい PaginationPosts 型を追加します。

    type PaginatedPosts { posts: [Post!]! nextToken: String }
  • [Save] を選択します。

  • 右側のデータ型ペインで、クエリタイプで新しく作成されたallPostフィールドを見つけ、 のアタッチを選択します。

  • アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "Scan" #if( ${context.arguments.count} ) ,"limit": $util.toJson($context.arguments.count) #end #if( ${context.arguments.nextToken} ) ,"nextToken": $util.toJson($context.arguments.nextToken) #end }

    このリゾルバーには、省略可能な 2 つの引数があります。count では、1 回の呼び出しで返される項目の最大数を指定し、nextToken は、次の結果セットを取得するために使用できます (nextToken の値がどのように生成されるかについては、後で説明します)。

  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    { "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }

    注 : このレスポンスマッピングテンプレートは、これまで他の例で使用したものとは異なります。allPost クエリの結果は PaginatedPosts であり、ポストのリストとページ分割トークンが含まれています。このオブジェクトの形状は、 AWS AppSync DynamoDB Resolver から返されるものと異なります。投稿のリストは AWS AppSync DynamoDB Resolver の結果itemsで呼び出されますが、 postsでは呼び出されますPaginatedPosts

  • [Save] を選択します。

Scan リクエストマッピングの詳細については、「Scan」リファレンスドキュメントを参照してください。

を呼び出しAPIてすべての投稿をスキャンする

これでリゾルバーが設定され、受信allPostクエリを DynamoDBScan オペレーションに変換する方法が AWS AppSync わかりました。ユーザーは、テーブルをスキャンしてすべてのポストを取得できるようになりました。

ただし、これまで使用してきたデータはすべて削除したため、これを試す前にテーブルにデータを入力しておく必要があります。

  • [クエリ] タブを選択します。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。

    mutation addPost { post1: addPost(id:1 author: "AUTHORNAME" title: "A series of posts, Volume 1" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post2: addPost(id:2 author: "AUTHORNAME" title: "A series of posts, Volume 2" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post3: addPost(id:3 author: "AUTHORNAME" title: "A series of posts, Volume 3" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post4: addPost(id:4 author: "AUTHORNAME" title: "A series of posts, Volume 4" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post5: addPost(id:5 author: "AUTHORNAME" title: "A series of posts, Volume 5" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post6: addPost(id:6 author: "AUTHORNAME" title: "A series of posts, Volume 6" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post7: addPost(id:7 author: "AUTHORNAME" title: "A series of posts, Volume 7" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post8: addPost(id:8 author: "AUTHORNAME" title: "A series of posts, Volume 8" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post9: addPost(id:9 author: "AUTHORNAME" title: "A series of posts, Volume 9" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

では、テーブルをスキャンして、一度に 5 個の結果を返しましょう。

  • 以下のクエリを [クエリ] ペインに貼り付けます。

    query allPost { allPost(count: 5) { posts { id title } nextToken } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • 最初の 5 個のポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "allPost": { "posts": [ { "id": "5", "title": "A series of posts, Volume 5" }, { "id": "1", "title": "A series of posts, Volume 1" }, { "id": "6", "title": "A series of posts, Volume 6" }, { "id": "9", "title": "A series of posts, Volume 9" }, { "id": "7", "title": "A series of posts, Volume 7" } ], "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRkJEdXdUK09hcnovRGhNTGxLTGdMUEFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF6ajFodkhKU1paT1pncTRaUUNBUkNBZ2dHWnJiR1dQWGxkMDB1N0xEdGY4Z2JsbktzRjRua1VCcks3TFJLcjZBTFRMeGFwVGJZMDRqOTdKVFQyYVRwSzdzbVdtNlhWWFVCTnFIOThZTzBWZHVkdDI2RlkxMHRqMDJ2QTlyNWJTUWpTbWh6NE5UclhUMG9KZWJSQ2JJbXBlaDRSVlg0Tis0WTVCN1IwNmJQWWQzOVhsbTlUTjBkZkFYMVErVCthaXZoNE5jMk50RitxVmU3SlJ5WmpzMEFkSGduM3FWd2VrOW5oeFVVd3JlK1loUks5QkRzemdiMDlmZmFPVXpzaFZ4cVJRbC93RURlOTcrRmVJdXZNby9NZ1F6dUdNbFRyalpNR3FuYzZBRnhwa0VlZTFtR0FwVDFISElUZlluakptYklmMGUzUmcxbVlnVHVSbDh4S0trNmR0QVoraEhLVDhuNUI3VnF4bHRtSnlNUXBrZGl6KzkyL3VzNDl4OWhrMnVxSW01ZFFwMjRLNnF0dm9ZK1BpdERuQTc5djhzb0grVytYT3VuQ2NVVDY4TVZ1Wk5KYkRuSEFSSEVlaTlVNVBTelU5RGZ6d2pPdmhqWDNJMWhwdWUrWi83MDVHVjlPQUxSTGlwZWZPeTFOZFhwZTdHRDZnQW00bUJUK2c1eC9Ec3ZDbWVnSDFDVXRTdHVuU1ZFa2JpZytQRC9oMUwyRTNqSHhVQldaa28yU256WUc0cG0vV1RSWkFVZHZuQT09In0=" } } }

5 つの結果と nextToken を取得しました。このトークンを使用して、次の結果セットを取得できます。

  • 前回の結果セットからの allPost を含めるように、nextToken クエリを更新します。

    query allPost { allPost( count: 5 nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRlluNktJRWl6V0ZlR3hJOVJkaStrZUFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5cW8yUGFSZThnalFpemRCTUNBUkNBZ2dHWk1JODhUNzhIOFVUZGtpdFM2ZFluSWRyVDg4c2lkN1RjZzB2d1k3VGJTTWpSQ2U3WjY3TkUvU2I1dWNETUdDMmdmMHErSGJSL0pteGRzYzVEYnE1K3BmWEtBdU5jSENJdWNIUkJ0UHBPWVdWdCtsS2U5L1pNcWdocXhrem1RaXI1YnIvQkt6dU5hZmJCdE93NmtoM2Jna1BKM0RjWWhpMFBGbmhMVGg4TUVGSjBCcXg3RTlHR1V5N0tUS0JLZlV3RjFQZ0JRREdrNzFYQnFMK2R1S2IrVGtZZzVYMjFrc3NyQmFVTmNXZmhTeXE0ZUJHSWhqZWQ5c3VKWjBSSTc2ZnVQdlZkR3FLNENjQmxHYXhpekZnK2pKK1FneEU1SXduRTNYYU5TR0I4QUpmamR2bU1wbUk1SEdvWjlMUUswclczbG14RDRtMlBsaTNLaEVlcm9pem5zcmdINFpvcXIrN2ltRDN3QkJNd3BLbGQzNjV5Nnc4ZnMrK2FnbTFVOUlKOFFrOGd2bEgySHFROHZrZXBrMWlLdWRIQ25LaS9USnBlMk9JeEVPazVnRFlzRTRUU09HUlVJTkxYY2MvdW1WVEpBMUthV2hWTlAvdjNlSnlZQUszbWV6N2h5WHVXZ1BkTVBNWERQdTdjVnVRa3EwK3NhbGZOd2wvSUx4bHNyNDVwTEhuVFpyRWZvVlV1bXZ5S2VKY1RUU1lET05hM1NwWEd2UT09In0=" ) { posts { id author } nextToken } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • 残りの 4 個のポストが、クエリペインの右側にある結果ペインに表示されます。9 個のポストのすべてをページ分割して、ポストは残っていないため、この結果セットに nextToken はありません。これは次のように表示されます。

    { "data": { "allPost": { "posts": [ { "id": "2", "title": "A series of posts, Volume 2" }, { "id": "3", "title": "A series of posts, Volume 3" }, { "id": "4", "title": "A series of posts, Volume 4" }, { "id": "8", "title": "A series of posts, Volume 8" } ], "nextToken": null } } }

allPostsBy作成者リゾルバーの設定 (DynamoDB クエリ)

DynamoDB ですべてのポストをスキャンだけでなく、特定の作成者が作成したポストを取得するクエリを DynamoDB に対して実行することもできます。前の手順で作成した DynamoDB テーブルには、既に author-index という GlobalSecondaryIndex があるため、DynamoDB の Query オペレーションでそれを使用して、特定の作成者が作成したすべてのポストを取得できます

  • [Schema (スキーマ)] タブを選択します。

  • [スキーマ] ペインの Query タイプを次のように変更して、新しい allPostsByAuthor クエリを追加します。

    type Query { allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts! allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }

    注 : このクエリでは、allPost クエリで使用したのと同じ PaginatedPosts 型を使用しています。

  • [Save] を選択します。

  • 右側のデータ型ペインで、クエリタイプで新しく作成された allPostsByAuthor フィールドを見つけ、 のアタッチを選択します。

  • アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "Query", "index" : "author-index", "query" : { "expression": "author = :author", "expressionValues" : { ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author) } } #if( ${context.arguments.count} ) ,"limit": $util.toJson($context.arguments.count) #end #if( ${context.arguments.nextToken} ) ,"nextToken": "${context.arguments.nextToken}" #end }

    allPost リゾルバーと同様に、このリゾルバーには、省略可能な 2 つの引数があります。count では、1 回の呼び出しで返される項目の最大数を指定し、nextToken は、次の結果セットを取得するために使用できます (nextToken の値は前回の呼び出しから取得できます)。

  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    { "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }

    注 : これは、allPost リゾルバーで使用したのと同じレスポンスマッピングテンプレートです。

  • [Save] を選択します。

Query リクエストマッピングの詳細については、「クエリ」リファレンスドキュメントを参照してください。

を呼び出しAPIて、作成者によるすべての投稿をクエリする

これでリゾルバーが設定され、受信allPostsByAuthorミューテーションをauthor-indexインデックスに対する DynamoDBQuery オペレーションに変換する方法が AWS AppSync わかりました。ユーザーは、テーブルをクエリして、特定の作成者によるポストをすべて取得できます。

ただし、これまで使用していたポストはすべて同じ作成者だったため、それを行う前に、テーブルにポストを追加しておきましょう。

  • [クエリ] タブを選択します。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。

    mutation addPost { post1: addPost(id:10 author: "Nadia" title: "The cutest dog in the world" content: "So cute. So very, very cute." url: "https://aws.amazon.com/appsync/" ) { author, title } post2: addPost(id:11 author: "Nadia" title: "Did you know...?" content: "AppSync works offline?" url: "https://aws.amazon.com/appsync/" ) { author, title } post3: addPost(id:12 author: "Steve" title: "I like GraphQL" content: "It's great" url: "https://aws.amazon.com/appsync/" ) { author, title } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

では、Nadia が作成したすべてのポストを返すクエリを実行しましょう。

  • 以下のクエリを [クエリ] ペインに貼り付けます。

    query allPostsByAuthor { allPostsByAuthor(author: "Nadia") { posts { id title } nextToken } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • Nadia が作成したすべてのポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you know...?" } ], "nextToken": null } } }

Query でのページ分割は Scan とまったく同じように動作します。例えば、AUTHORNAME によるすべてのポストを検索して、一度に 5 個ずつ取得します。

  • 以下のクエリを [クエリ] ペインに貼り付けます。

    query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" count: 5 ) { posts { id title } nextToken } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • AUTHORNAME が作成したすべてのポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "6", "title": "A series of posts, Volume 6" }, { "id": "4", "title": "A series of posts, Volume 4" }, { "id": "2", "title": "A series of posts, Volume 2" }, { "id": "7", "title": "A series of posts, Volume 7" }, { "id": "1", "title": "A series of posts, Volume 1" } ], "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ==" } } }
  • 次のように、nextToken 引数を、前回のクエリで返された値に更新します。

    query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" count: 5 nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ==" ) { posts { id title } nextToken } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • AUTHORNAME が作成した残りのポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "8", "title": "A series of posts, Volume 8" }, { "id": "5", "title": "A series of posts, Volume 5" }, { "id": "3", "title": "A series of posts, Volume 3" }, { "id": "9", "title": "A series of posts, Volume 9" } ], "nextToken": null } } }

セット型の使用

ここまでの Post 型は、フラットなキーと値のオブジェクトでした。セット、リスト、マップなど、 AWS AppSyncDynamoDB リゾルバーを使用して複雑なオブジェクトをモデル化することもできます。

Post 型を更新して、タグを含めましょう。1 つのポストには、DynamoDB に文字列として保存されているタグを 0 個以上付けることができます。タグを追加および削除するミューテーションと、特定のタグが付いているポストをスキャンする新しいクエリもセットアップします。

  • [Schema (スキーマ)] タブを選択します。

  • [スキーマ] ペインの Post タイプを次のように変更して、新しい tags フィールドを追加します。

    type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] }
  • [スキーマ] ペインの Query タイプを次のように変更して、新しい allPostsByTag クエリを追加します。

    type Query { allPostsByTag(tag: String!, count: Int, nextToken: String): PaginatedPosts! allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts! allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
  • [スキーマ] ペインの Mutation タイプを変更して、新しい addTagremoveTag ミューテーションを次のように追加します。

    type Mutation { addTag(id: ID!, tag: String!): Post removeTag(id: ID!, tag: String!): Post deletePost(id: ID!, expectedVersion: Int): Post upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }
  • [Save] を選択します。

  • 右側のデータ型ペインで、クエリタイプで新しく作成されたallPostsByタグフィールドを見つけ、 のアタッチを選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "Scan", "filter": { "expression": "contains (tags, :tag)", "expressionValues": { ":tag": $util.dynamodb.toDynamoDBJson($context.arguments.tag) } } #if( ${context.arguments.count} ) ,"limit": $util.toJson($context.arguments.count) #end #if( ${context.arguments.nextToken} ) ,"nextToken": $util.toJson($context.arguments.nextToken) #end }
  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    { "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }
  • [Save] を選択します。

  • 右側のデータ型ペインで、ミューテーションタイプで新しく作成されたaddTagフィールドを見つけ、アタッチ を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "ADD tags :tags, version :plusOne", "expressionValues" : { ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] }, ":plusOne" : { "N" : 1 } } } }
  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)
  • [Save] を選択します。

  • 右側のデータ型ペインで、ミューテーションタイプで新しく作成されたremoveTagフィールドを見つけ、アタッチ を選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "DELETE tags :tags ADD version :plusOne", "expressionValues" : { ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] }, ":plusOne" : { "N" : 1 } } } }
  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)
  • [Save] を選択します。

API を呼び出してタグを操作する

リゾルバーをセットアップしたので、受信する addTag、、removeTagおよび allPostsByTagリクエストを DynamoDBUpdateItem および Scanオペレーションに変換する AWS AppSync 方法について説明します。

それを試すには、前のステップで作成したポストのいずれかを選択します。例えば、Nadia が作成したポストを使用しましょう。

  • [クエリ] タブを選択します。

  • 以下のクエリを [クエリ] ペインに貼り付けます。

    query allPostsByAuthor { allPostsByAuthor( author: "Nadia" ) { posts { id title } nextToken } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • Nadia のすべてのポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you known...?" } ], "nextToken": null } } }
  • タイトルが「"The cutest dog in the world"」のポストを使用しましょう。id は後で使用するため書き留めておきます。

では、dog タグを追加してみましょう。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。また、id 引数を、前にメモしておいた値に更新する必要があります。

    mutation addTag { addTag(id:10 tag: "dog") { id title tags } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • ポストが新しいタグで更新されています。

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }

次のようにタグを追加できます。

  • puppy に変更するように、tag 引数を更新します。

    mutation addTag { addTag(id:10 tag: "puppy") { id title tags } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • ポストが新しいタグで更新されています。

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } } }

タグを削除することもできます。

  • 以下のミューテーションを [クエリ] ペインに貼り付けます。また、id 引数を、前にメモしておいた値に更新する必要があります。

    mutation removeTag { removeTag(id:10 tag: "puppy") { id title tags } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • ポストが更新され、puppy タグが削除されています。

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }

タグが付いているすべてのポストを検索することもできます。

  • 以下のクエリを [クエリ] ペインに貼り付けます。

    query allPostsByTag { allPostsByTag(tag: "dog") { posts { id title tags } nextToken } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • 次のように dog タグが付いているすべての投稿が返されます。

    { "data": { "allPostsByTag": { "posts": [ { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } ], "nextToken": null } } }

リスト型とマップ型の使用

DynamoDB のセット型を使用するだけでなく、DynamoDB のリスト型やマップ型を使用して、複雑なデータを単一のオブジェクトにモデル化することもできます。

ポストにコメントを追加する機能を追加しましょう。これは、DynamoDB 内の Post オブジェクトで、マップ型オブジェクトのリスト型としてモデル化されます。

注 : 実際のアプリケーションでは、独自のテーブル内のコメントをモデル化します。このチュートリアルでは、Post テーブルにコメントを追加しているだけです。

  • [Schema (スキーマ)] タブを選択します。

  • [Schema (スキーマ)] ペインで、次のように新しい Comment 型を追加します。

    type Comment { author: String! comment: String! }
  • [スキーマ] ペインの Post タイプを次のように変更して、新しい comments フィールドを追加します。

    type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] comments: [Comment!] }
  • [スキーマ] ペインの Mutation タイプを次のように変更して、新しい addComment ミューテーションを追加します。

    type Mutation { addComment(id: ID!, author: String!, comment: String!): Post addTag(id: ID!, tag: String!): Post removeTag(id: ID!, tag: String!): Post deletePost(id: ID!, expectedVersion: Int): Post upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }
  • [Save] を選択します。

  • 右側のデータ型ペインで、ミューテーションタイプで新しく作成されたaddCommentフィールドを見つけ、 のアタッチを選択します。

  • [Data source name (データソース名)] で [PostDynamoDBTable] を選択します。

  • 以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "SET comments = list_append(if_not_exists(comments, :emptyList), :newComment) ADD version :plusOne", "expressionValues" : { ":emptyList": { "L" : [] }, ":newComment" : { "L" : [ { "M": { "author": $util.dynamodb.toDynamoDBJson($context.arguments.author), "comment": $util.dynamodb.toDynamoDBJson($context.arguments.comment) } } ] }, ":plusOne" : $util.dynamodb.toDynamoDBJson(1) } } }

    この更新式によって、新しいコメントが含まれているリストが、既存の comments リストに追加されます。リストがまだ存在しない場合は作成されます。

  • 以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。

    $utils.toJson($context.result)
  • [Save] を選択します。

API を呼び出してコメントを追加する

リゾルバーをセットアップしたので、受信addCommentリクエストを DynamoDBUpdateItem オペレーションに変換する AWS AppSync 方法について説明します。

タグを追加したのと同じポストにコメントを追加して、試してみましょう。

  • [クエリ] タブを選択します。

  • 以下のクエリを [クエリ] ペインに貼り付けます。

    mutation addComment { addComment( id:10 author: "Steve" comment: "Such a cute dog." ) { id comments { author comment } } }
  • [Execute query (クエリを実行)] (オレンジ色の再生ボタン) を選択します。

  • Nadia のすべてのポストが、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。

    { "data": { "addComment": { "id": "10", "comments": [ { "author": "Steve", "comment": "Such a cute dog." } ] } } }

このリクエストを複数回実行すると、複数のコメントがリストに追加されます。

結論

このチュートリアルでは、 AWS AppSync と GraphQL を使用して DynamoDB の Post オブジェクトを操作APIできる を構築しました。詳細については、「リゾルバーのマッピングテンプレートリファレンス」を参照してください。

クリーンアップするには、コンソールAPIから AppSync GraphQL を削除できます。

このチュートリアル用に作成した DynamoDB テーブルとIAMロールを削除するには、以下を実行してAWSAppSyncTutorialForAmazonDynamoDBスタックを削除するか、 AWS CloudFormation コンソールにアクセスしてスタックを削除します。

aws cloudformation delete-stack \ --stack-name AWSAppSyncTutorialForAmazonDynamoDB