翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
DynamoDB リゾルバーを使用したシンプルなポストアプリケーションの作成
注記
現在、主に APPSYNC_JS ランタイムとそのドキュメントをサポートしています。APPSYNC_JS ランタイムとそのガイドをここで使用することを検討してください。
このチュートリアルでは、独自の Amazon DynamoDB テーブルを に持ち込み AWS AppSync 、GraphQL に接続する方法を示しますAPI。
DynamoDB リソースをユーザーに代わって AWS AppSync プロビジョニングできます。または、必要であれば、データソースとリゾルバーを作成することで、既存のテーブルを GraphQL スキーマに接続できます。いずれの場合も、GraphQL ステートメントを使用して DynamoDB データベースへの読み取りと書き込みを行うことができ、リアルタイムデータをサブスクライブできます。
GraphQL ステートメントが DynamoDB オペレーションに変換され、レスポンスが GraphQL に変換されるように、特定の設定ステップを完了しておく必要があります。このチュートリアルでは、いくつかの実際のシナリオおよびデータアクセスパターンを使用して、その設定手順の概要を示します。
DynamoDB テーブルのセットアップ
このチュートリアルを開始するには、まず以下の手順に従って AWS リソースをプロビジョニングする必要があります。
-
の次の 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 。
これにより、以下の項目が作成されます。
-
データを保持するDynamoDBテーブルが
AppSyncTutorial-Post
呼び出されます。Post
-
AWS AppSync が
Post
テーブルとやり取りできるようにするIAMロールと関連付けられたIAM管理ポリシー。
-
-
スタックと作成されたリソースの詳細については、次のCLIコマンドを実行します。
aws cloudformation describe-stacks --stack-name AWSAppSyncTutorialForAmazonDynamoDB
-
そのリソースを削除するには、次のコマンドを実行します。
aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB
GraphQL の作成 API
API で GraphQL を作成するには AWS AppSync:
-
にサインイン AWS Management Console し、AppSync コンソール
を開きます。 -
APIs ダッシュボード で、「 の作成API」を選択します。
-
-
Amazon DynamoDB ウィンドウから APIまたは をインポートする で、ゼロからビルド を選択します。
-
同じウィンドウの右にある [開始] を選択します。
-
-
API 名前フィールドで、 の名前を API に設定します
AWSAppSyncTutorial
。 -
[Create] (作成) を選択します。
AWS AppSync コンソールは、APIキー認証モードAPIを使用して新しい GraphQL を作成します。コンソールを使用して、GraphQL の残りの部分をセットアップAPIし、このチュートリアルの残りの部分に対してクエリを実行できます。
基本的な投稿の定義 API
AWS AppSync GraphQL を作成したらAPI、投稿データの基本作成、取得、削除を許可する基本スキーマを設定できます。
-
にサインイン AWS Management Console し、AppSync コンソール
を開きます。 -
APIs ダッシュボード で、API先ほど作成した を選択します。
-
-
サイドバーで [スキーマ] を選択します。
-
[スキーマ] ペインで、内容を次のコードに置き換えます。
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! }
-
-
[Save] を選択します。
このスキーマでは、Post
型と、Post
オブジェクトを追加および取得するオペレーションを定義しています。
DynamoDB テーブル用のデータソースの設定
次に、スキーマで定義されているクエリとミューテーションを AppSyncTutorial-Post
DynamoDB テーブルにリンクします。
まず、テーブルに注意 AWS AppSync する必要があります。これを行うには、 でデータソースを設定します AWS AppSync。
-
にサインイン AWS Management Console し、AppSync コンソール
を開きます。 -
APIs ダッシュボード で、GraphQL を選択しますAPI。
-
サイドバー で [データソース] を選択します。
-
-
[データソースを作成] を選択します。
-
データソース名には、
PostDynamoDBTable
を入力します。 -
[データソースタイプ] として [Amazon DynamoDB テーブル] を選択します。
-
リージョン では、US-WEST-2 を選択します。
-
テーブル名 で、AppSyncTutorial-Post DynamoDB テーブルを選択します。
-
新しい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:*" ] } ] }
-
-
[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
型と異なる場合に便利です。ただし、この例では、両方のシェイプが同じであるため、データをそのまま渡します。
リゾルバーをセットアップするには、以下の手順に従います。
-
にサインイン AWS Management Console し、AppSync コンソール
を開きます。 -
APIs ダッシュボード で、GraphQL を選択しますAPI。
-
サイドバー で [データソース] を選択します。
-
-
[データソースを作成] を選択します。
-
データソース名には、
PostDynamoDBTable
を入力します。 -
[データソースタイプ] として [Amazon DynamoDB テーブル] を選択します。
-
リージョン では、US-WEST-2 を選択します。
-
テーブル名 で、AppSyncTutorial-Post DynamoDB テーブルを選択します。
-
新しい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:*" ] } ] }
-
-
[Create] (作成) を選択します。
-
[Schema (スキーマ)] タブを選択します。
-
右側のデータ型ペインで、ミューテーションタイプの addPostフィールドを検索し、「 をアタッチ」を選択します。
-
アクションメニュー で、ランタイムの更新 を選択し、ユニットリゾルバー (VTL のみ) を選択します。
-
[Data source name (データソース名)] で [PostDynamoDBTable] を選択します。
-
以下のコードを [リクエストマッピングテンプレートの設定] に貼り付けます。
{ "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
が使用されているため数値フィールドです。最後に、ups
、downs
およびversion
フィールドの初期化も行っています。このチュートリアルでは、DynamoDB に挿入された新しい項目にインデックスを付ける GraphQL
ID!
タイプが、 という自動 ID 生成用のユーティリティを持つ client arguments. AWS AppSync comes の一部として提供されることを指定しました。$utils.autoId()
これは、 の形式でも使用できます"id" : { "S" : "${$utils.autoId()}" }
。 DynamoDB そのため、id: ID!
をaddPost()
のスキーマ定義から除外するだけで、自動的に挿入されます。このチュートリアルではこの手法を使用しませんが、DynamoDB テーブルに書き込む場合はこの手法を検討することをお勧めします。マッピングテンプレートの詳細については、「リゾルバーのマッピングテンプレートの概要」リファレンスドキュメントを参照してください。 GetItem リクエストマッピングの詳細については、GetItemリファレンスドキュメントを参照してください。型の詳細については、「型システム (リクエストマッピング)」リファレンスドキュメントを参照してください。
-
以下のコードを [レスポンスマッピングテンプレートの設定] に貼り付けます。
$utils.toJson($context.result)
注 :
AppSyncTutorial-Post
テーブルでのデータのシェイプは GraphQL でのPost
型のシェイプと厳密に一致しているため、このレスポンスマッピングテンプレートは結果をそのまま渡すだけです。また、このチュートリアルのすべての例では、これと同じレスポンスマッピングテンプレートだけを使用しているため、作成するファイルはこの 1 つだけです。 -
[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 は、リクエストマッピングドキュメントを使用して DynamoDB
PutItem
リクエストを生成および実行しました。 -
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
クエリに、id
、author
および 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
フィールドで指定されています。その式では、author
、title
、content
、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
ミューテーションを修正します。
-
[Schema (スキーマ)] タブを選択します。
-
[Schema (スキーマ)] ペインで
Mutation
型のupdatePost
フィールドを変更して、author
、title
、content
、url
の各引数から感嘆符を除去し、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! }
-
[Save] を選択します。
-
右側のデータ型ペインで、ミューテーションタイプの updatePostフィールドを見つけます。
-
PostDynamoDBTable を選択して既存のリゾルバーを開きます。
-
[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) } } }
-
[Save] を選択します。
このテンプレートでは、より複雑な例を示します。マッピングテンプレートの力と柔軟性を示しています。すべての引数をループ処理し、id
と expectedVersion
をスキップしています。引数が何かに設定されている場合、 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 に title
content
フィールドのみを更新するように依頼しました。その他のフィールドは元のままです (増分する version
フィールドは除く)。title
属性を新しい値に設定し、ポストから content
属性を削除しています。author
、url
ups
、downs
の各フィールドは変更されません。
リクエストはまったく同じままで、このミューテーションをもう一度実行してみます。次のようなレスポンスが表示されます。
{ "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
タイプを変更して、新しいupvotePost
とdownvotePost
ミューテーションを次のように追加します。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
タイプを変更して、新しいaddTag
とremoveTag
ミューテーションを次のように追加します。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