翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
DynamoDB JavaScript リゾルバーを使用したシンプルなポストアプリケーションの作成
このチュートリアルでは、Amazon DynamoDB テーブルを にインポート AWS AppSync して接続し、独自のアプリケーションで活用できる JavaScript パイプラインリゾルバーAPIを使用して、フル機能の GraphQL を構築します。
AWS AppSync コンソールを使用して Amazon DynamoDB リソースをプロビジョニングし、リゾルバーを作成し、データソースに接続します。また、GraphQL ステートメントを使用して Amazon DynamoDB データベースへの読み取りと書き込みを行うことができ、リアルタイムデータをサブスクライブできます。
GraphQL ステートメントが Amazon DynamoDB オペレーションに変換され、レスポンスが GraphQL に変換されるように、特定のステップを完了しておく必要があります。このチュートリアルでは、いくつかの実際のシナリオおよびデータアクセスパターンを使用して、その設定手順の概要を示します。
GraphQL の作成 API
APIで GraphQL を作成するには AWS AppSync
-
AppSync コンソールを開き、 の作成 APIを選択します。
-
[最初から設計] を選択し、[次へ] を選択します。
-
に名前を付けAPI
PostTutorialAPI
、次へ を選択します。残りのオプションはデフォルト設定値のまま、レビューページに移動し、Create
を選択します。
AWS AppSync コンソールは新しい GraphQL を作成しますAPI。ディタルトでは、APIキー認証モードを使用します。コンソールを使用して、残りの GraphQL をセットアップAPIし、このチュートリアルの残りの部分に対してクエリを実行できます。
基本的な投稿の定義 API
GraphQL が完成したらAPI、投稿データの基本作成、取得、削除を許可する基本スキーマを設定できます。
スキーマにデータを追加するには
-
でAPI、スキーマタブを選択します。
-
Post
オブジェクトを追加および取得するためのPost
タイプと操作addPost
を定義するスキーマを作成します。[スキーマ] ペインで、内容を次のコードに置き換えます。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 Schema] を選択します。
Amazon DynamoDB テーブルのセットアップ
AWS AppSync コンソールは、独自の AWS リソースを Amazon DynamoDB テーブルに保存するために必要なリソースをプロビジョニングするのに役立ちます。このステップでは、投稿を保存する Amazon DynamoDB テーブルを作成します。また、後で使用するセカンダリインデックスも設定します。
Amazon DynamoDB テーブルを作成するには
-
[スキーマ] ページで、[リソースを作成] を選択します。
-
[既存のタイプを使用] を選択し、
Post
タイプを選択します。 -
[セカンダリインデックス] セクションで、[インデックスを追加] を選択します。
-
インデックス
author-index
の名前 -
Primary key
をauthor
に、Sort
キーをNone
に設定します。 -
GraphQL の自動生成を無効にします。この例では、リゾルバーを自分で作成します。
-
[Create] (作成) を選択します。
これで、PostTable
という新しいデータソースができました。サイドタブの [データソース] にアクセスすると確認できます。このデータソースを使用して、クエリとミューテーションを Amazon DynamoDB テーブルにリンクします。
addPost リゾルバーの設定 (Amazon DynamoDB PutItem)
これで AWS AppSync 、Amazon DynamoDB テーブルを認識できたので、リゾルバーを定義することで、個々のクエリやミューテーションにリンクできます。最初に作成するリゾルバーは、 を使用するaddPost
パイプラインリゾルバーです。これにより JavaScript、Amazon DynamoDB テーブルに投稿を作成できます。パイプラインリゾルバーには以下のコンポーネントがあります。
-
リゾルバーをアタッチする、GraphQL スキーマ内の場所。この例では、
createPost
型のMutation
フィールドにリゾルバーをセットアップしています。このリゾルバーは、呼び出し元がミューテーション{ addPost(...){...} }
を呼び出したときに呼び出されます。 -
このリゾルバーで使用するデータソース。この例では、
post-table-for-tutorial
DynamoDB テーブルにエントリを追加できるように、前に定義した データソースを使用します。 -
リクエストハンドラー。リクエストハンドラーは、発信者からの受信リクエストを処理し、DynamoDB に対して実行する の手順に変換 AWS AppSync する関数です。 DynamoDB
-
レスポンスハンドラー。レスポンスハンドラーの仕事は、DynamoDB からのレスポンスに対応して、それを GraphQL で想定されているものに変換し直すことです。これは、DynamoDB でのデータのシェイプが GraphQL での
Post
型と異なる場合に便利です。ただし、この例では、両方のシェイプが同じであるため、データをそのまま渡します。
リゾルバーをセットアップするには
-
でAPI、スキーマタブを選択します。
-
リゾルバー ペインで、
Mutation
型の下にあるaddPost
フィールドを探し、「アタッチ」を選択します。 -
データソースを選択し、[作成] を選択します。
-
コードエディターで、コードを次のスニペットに置き換えます。
import { util } from '@aws-appsync/utils' import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { const item = { ...ctx.arguments, ups: 1, downs: 0, version: 1 } const key = { id: ctx.args.id ?? util.autoId() } return ddb.put({ key, item }) } export function response(ctx) { return ctx.result }
-
[Save] を選択します。
注記
このコードでは、DynamoDB リクエストを簡単に作成できる DynamoDB モジュール utils を使用します。
AWS AppSync には、 という名前の自動 ID 生成用のユーティリティが付属しています。これはutil.autoId()
、新しい投稿の ID を生成するために使用されます。ID を指定しないと、ユーティリティによって自動的に ID が生成されます。
const key = { id: ctx.args.id ?? util.autoId() }
で使用できるユーティリティの詳細については JavaScript、JavaScript「リゾルバーと関数のランタイム機能」を参照してください。
API を呼び出して投稿を追加する
これでリゾルバーが設定され、着信addPost
ミューテーションを Amazon DynamoDB PutItem
オペレーションに変換 AWS AppSync できるようになりました。ユーザーはミューテーションを実行してテーブルに何かを入れることができるようになりました。
オペレーションを実行するには
-
でAPI、クエリタブを選択します。
-
以下のミューテーションを [クエリ] ペインに追加します。
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 } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
addPost
] を選択します。新しく作成されたポストの結果が、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。{ "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 はリゾルバーのリクエストハンドラーを実行します。
ddb.put
関数は以下のようなPutItem
リクエストを作成します。{ operation: 'PutItem', key: { id: { S: '123' } }, attributeValues: { downs: { N: 0 }, author: { S: 'AUTHORNAME' }, ups: { N: 1 }, title: { S: 'Our first post!' }, version: { N: 1 }, content: { S: 'This is our first post.' }, url: { S: 'https://aws.amazon.com/appsync/' } } }
-
AWS AppSync はこの値を使用して Amazon 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 }
-
レスポンスハンドラーは結果をすぐに返します (
return ctx.result
)。 -
最終結果は GraphQL のレスポンスに表示されます。
getPost リゾルバーのセットアップ (Amazon DynamoDB GetItem)
これで、 Amazon DynamoDB テーブルにデータを追加できるようになりました。次は、からデータを取得できるように、getPost
クエリを設定する必要があります。そのためには、別のリゾルバーを設定します。
リソースを追加するには、次の手順に従います。
-
でAPI、スキーマタブを選択します。
-
右側の [リゾルバー] ペインで、
Query
タイプのgetPost
フィールドを見つけて [アタッチ] を選択します。 -
データソースを選択し、[作成] を選択します。
-
コードエディタで、コードを次のスニペットに置き換えます。
import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { return ddb.get({ key: { id: ctx.args.id } }) } export const response = (ctx) => ctx.result
-
リゾルバーを保存します。
注記
このリゾルバーでは、レスポンスハンドラーに矢印関数式を使用しています。
API を呼び出して投稿を取得する
これでリゾルバーが設定され、受信getPost
クエリを Amazon DynamoDB GetItem
オペレーションに変換する AWS AppSync 方法について説明します。次は、先ほど作成したポストを取得するクエリを実行します。
クエリを実行するには
-
でAPI、クエリタブを選択します。
-
クエリ ペインで次のコードを追加し、投稿を作成した後にコピーした ID を使用します。
query getPost { getPost(id: "123") { id author title content url ups downs version } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
getPost
] を選択します。新しく作成されたポストの結果が、クエリペインの右側にある結果ペインに表示されます。 -
Amazon 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 } } }
別の方法として、次の例を指定します。
query getPost { getPost(id: "123") { id author title } }
getPost
クエリが id
、author
、title
のみを必要とする場合は、DynamoDB から AWS AppSyncへの不要なデータ転送を避けるため、プロジェクション式を使用して DynamoDB テーブルから必要な属性のみを指定するようにリクエスト関数を変更できます。例えば、リクエスト関数は以下のスニペットのようになっているかもしれません。
import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { return ddb.get({ key: { id: ctx.args.id }, projection: ['author', 'id', 'title'], }) } export const response = (ctx) => ctx.result
selectionSetList と を使用して getPost
を表すこともできますexpression
。
import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { const projection = ctx.info.selectionSetList.map((field) => field.replace('/', '.')) return ddb.get({ key: { id: ctx.args.id }, projection }) } export const response = (ctx) => ctx.result
updatePost ミューテーションを作成する (Amazon DynamoDB UpdateItem)
これで、Amazon DynamoDB 内の Post
オブジェクトを作成および取得できるようになりました。次は、オブジェクトを更新できるように、新しいミューテーションを設定します。すべてのフィールドを指定する必要がある addPost
ミューテーションと比較すると、このミューテーションでは変更するフィールドのみを指定できます。また、変更するバージョンを指定できる新しい expectedVersion
引数が導入されました。オブジェクトの最新バージョンを変更していることを確認する条件を設定します。そのためには、UpdateItem
Amazon DynamoDB operation.sc を使用します。
リゾルバーを更新するには
-
でAPI、スキーマタブを選択します。
-
[スキーマ] ペインの
Mutation
タイプを次のように変更して、新しいupdatePost
ミューテーションを追加します。type Mutation { updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( id: ID author: String! title: String! content: String! url: String! ): Post! }
-
[Save Schema] を選択します。
-
右側の [リゾルバー] ペインで、
Mutation
型の新しく作成されたupdatePost
フィールドを見つけて、[アタッチ] を選択します。以下のスニペットを使用して新しいリゾルバーを作成します。import { util } from '@aws-appsync/utils'; import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { id, expectedVersion, ...rest } = ctx.args; const values = Object.entries(rest).reduce((obj, [key, value]) => { obj[key] = value ?? ddb.operations.remove(); return obj; }, {}); return ddb.update({ key: { id }, condition: { version: { eq: expectedVersion } }, update: { ...values, version: ddb.operations.increment(1) }, }); } export function response(ctx) { const { error, result } = ctx; if (error) { util.appendError(error.message, error.type); } return result;
-
加えた変更を保存します。
このリゾルバーは ddb.update
を使用して Amazon DynamoDB の作成 UpdateItem
を行います。Amazon DynamoDB では、項目全体が書き込まれるのではなく、特定の属性が更新されるようにします。これを行うには、Amazon DynamoDB の更新式を使用します。
ddb.update
関数はキーと更新オブジェクトを引数として取得します。次に、入力された引数の値をチェックします。値がnull
に設定されたら、DynamoDB remove
オペレーションを使用して、値を DynamoDB 項目から削除する必要があることを通知します。
また、新しい condition
セクションがあります。条件式を使用すると、 AWS AppSync および Amazon DynamoDB に対して、オペレーションが実行される前に、Amazon DynamoDB に既に存在するオブジェクトの状態に基づいてリクエストが成功するかどうかを指示できます。この例では、Amazon DynamoDB に現在ある項目の version
フィールドが expectedVersion
引数と厳密に一致する場合にのみ、UpdateItem
リクエストが成功するように指示しています。項目が更新されたら、version
の値をインクリメントする必要があります。これは操作機能 increment
を使えば簡単に行えます。
条件式の詳細については、「条件式リファレンス」ドキュメントを参照してください。
UpdateItem
リクエストの詳細については、 UpdateItemドキュメントと DynamoDB モジュールドキュメントを参照してください。
更新式を記述する方法の詳細については、DynamoDB UpdateExpressionsドキュメントを参照してください。
API を呼び出して投稿を更新する
新しいリゾルバーで Post
オブジェクトを更新してみましょう。
オブジェクトを更新するには
-
でAPI、クエリタブを選択します。
-
以下のミューテーションを [クエリ] ペインに貼り付けます。また、
id
引数を、前にメモしておいた値に更新する必要があります。mutation updatePost { updatePost( id:123 title: "An empty story" content: null expectedVersion: 1 ) { id author title content url ups downs version } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
updatePost
] を選択します。 -
Amazon 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": 2 } } }
このリクエストでは、 AWS AppSync と Amazon DynamoDB に title
フィールドと content
フィールドのみを更新するように依頼しました。その他のフィールドは元のままです (増分する version
フィールドは除く)。title
属性を新しい値に設定し、ポストから content
属性を削除しています。author
、url
ups
、downs
の各フィールドは変更されません。リクエストはまったく同じままで、このミューテーションをもう一度実行してみます。次のようなレスポンスが表示されます。
{ "data": { "updatePost": null }, "errors": [ { "path": [ "updatePost" ], "data": null, "errorType": "DynamoDB:ConditionalCheckFailedException", "errorInfo": null, "locations": [ { "line": 2, "column": 3, "sourceName": null } ], "message": "The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: 1RR3QN5F35CS8IV5VR4OQO9NNBVV4KQNSO5AEMVJF66Q9ASUAAJG)" } ] }
このリクエストは、条件式が false
と評価されるため失敗します。
-
このリクエストを最初に実行したときに、Amazon DynamoDB 内のこの投稿の
version
フィールドの値は1
であり、expectedVersion
引数と一致していました。このリクエストは成功し、Amazon DynamoDB でversion
フィールドが2
に増分されました。 -
このリクエストを 2 回目に実行したときに、Amazon DynamoDB 内のこのポストの
version
フィールドの値は2
であり、expectedVersion
引数と一致していませんでした。
このパターンは通常、「楽観的ロック」と呼ばれます。
投票ミューテーションを作成する (Amazon DynamoDB UpdateItem)
Post
タイプには、賛成票と反対票を記録できるようにする ups
と downs
フィールドが含まれます。ただし、現時点では、 APIでは何もできません。投稿に賛成および反対するための、いくつかのミューテーションを追加してみましょう。
ミューテーションを追加するには
-
でAPI、スキーマタブを選択します。
-
[スキーマ] ペインの
Mutation
型を変更してDIRECTION
列挙型を追加し、新しい投票ミューテーションを追加します。type Mutation { vote(id: ID!, direction: DIRECTION!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( id: ID, author: String!, title: String!, content: String!, url: String! ): Post! } enum DIRECTION { UP DOWN }
-
[Save Schema] を選択します。
-
右側の [リゾルバー] ペインで、
Mutation
型の新しく作成されたvote
フィールドを見つけて、[アタッチ] を選択します。コードを作成して次のスニペットに置き換えることで、新しいリゾルバーを作成します。import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const field = ctx.args.direction === 'UP' ? 'ups' : 'downs'; return ddb.update({ key: { id: ctx.args.id }, update: { [field]: ddb.operations.increment(1), version: ddb.operations.increment(1), }, }); } export const response = (ctx) => ctx.result;
-
加えた変更を保存します。
API を呼び出して投稿をアップボットまたはダウンボットする
新しいリゾルバーがセットアップされたので、受信upvotePost
またはdownvote
ミューテーションを Amazon DynamoDB UpdateItem
オペレーションに変換する方法 AWS AppSync を理解します。これで、先ほど作成したポストに賛成または反対するミューテーションを実行できるようになりました。
ミューテーションを実行するには
-
でAPI、クエリタブを選択します。
-
以下のミューテーションを [クエリ] ペインに貼り付けます。また、
id
引数を、前にメモしておいた値に更新する必要があります。mutation votePost { vote(id:123, direction: UP) { id author title content url ups downs version } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
votePost
] を選択します。 -
Amazon DynamoDB で更新された投稿が、クエリペインの右側にある結果ペインに表示されます。これは次のように表示されます。
{ "data": { "vote": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 0, "version": 4 } } }
-
もう何回か [実行] を選択します。このクエリを実行するたびに、
ups
フィールドとversion
フィールドが1
つずつ増加することを確認できます。 -
クエリを変更して、別の
DIRECTION
を呼び出してください。mutation votePost { vote(id:123, direction: DOWN) { id author title content url ups downs version } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
votePost
] を選択します。今度は、このクエリを実行するたびに、
downs
フィールドとversion
フィールドが1
つずつ増加することを確認できます。
deletePost リゾルバーの設定 (Amazon DynamoDB DeleteItem)
次に、投稿を削除するミューテーションを作成します。そのためには、DeleteItem
Amazon DynamoDB オペレーションを使用します。
ミューテーションを追加するには
-
スキーマで、「スキーマ」タブを選択します。
-
[スキーマ] ペインの
Mutation
型を変更して、新しいdeletePost
ミューテーションを追加します。type Mutation { deletePost(id: ID!, expectedVersion: Int): Post vote(id: ID!, direction: DIRECTION!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( id: ID author: String!, title: String!, content: String!, url: String! ): Post! }
-
今回は、
expectedVersion
フィールドをオプションにしました。[スキーマを保存] を選択します。 -
右側の [リゾルバー] ペインで、
delete
タイプから新しく作成されたMutation
フィールドを探し、[アタッチ] を選択します。次のコードを使用して新しいリゾルバーを作成します。import { util } from '@aws-appsync/utils' import { util } from '@aws-appsync/utils'; import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { let condition = null; if (ctx.args.expectedVersion) { condition = { or: [ { id: { attributeExists: false } }, { version: { eq: ctx.args.expectedVersion } }, ], }; } return ddb.remove({ key: { id: ctx.args.id }, condition }); } export function response(ctx) { const { error, result } = ctx; if (error) { util.appendError(error.message, error.type); } return result; }
注記
expectedVersion
引数は省略可能な引数です。呼び出し元がリクエストでexpectedVersion
引数を設定していると、項目が既に削除されている場合、または Amazon DynamoDB 内の投稿のversion
属性がexpectedVersion
と完全に一致する場合にのみ、DeleteItem
リクエストが成功することを許可する条件が、テンプレートによって追加されます。この引数が省略されている場合は、DeleteItem
リクエストで条件式が指定されていません。version
の値や項目が Amazon DynamoDB に存在するかどうかに関係なく、成功します。注意: 項目を削除する場合でも、その項目がまだ削除されていなければ、削除された項目を返すことができます。
DeleteItem
リクエストの詳細については、DeleteItemドキュメントを参照してください。
API を呼び出して投稿を削除する
これでリゾルバーが設定され、着信delete
ミューテーションを Amazon DynamoDB DeleteItem
オペレーションに変換 AWS AppSync する方法について説明します。ユーザーはミューテーションを実行してテーブル内の何かを削除できるようになりました。
ミューテーションを実行するには
-
でAPI、クエリタブを選択します。
-
以下のミューテーションを [クエリ] ペインに貼り付けます。また、
id
引数を、前にメモしておいた値に更新する必要があります。mutation deletePost { deletePost(id:123) { id author title content url ups downs version } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
deletePost
] を選択します。 -
この投稿が Amazon DynamoDB から削除されます。は、Amazon 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
呼び出しによって実際に Amazon 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 } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
addPost
] を選択します。 -
新しく作成されたポストの結果が、クエリペインの右側にある結果ペインに表示されます。新しく作成されたオブジェクトの
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 } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
deletePost
] を選択します。以下のレスポンスが返されます。{ "data": { "deletePost": null }, "errors": [ { "path": [ "deletePost" ], "data": null, "errorType": "DynamoDB:ConditionalCheckFailedException", "errorInfo": null, "locations": [ { "line": 2, "column": 3, "sourceName": null } ], "message": "The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: 7083O037M1FTFRK038A4CI9H43VV4KQNSO5AEMVJF66Q9ASUAAJG)" } ] }
-
このリクエストは、条件式が
false
と評価されるため失敗します。Amazon DynamoDBversion
の投稿の値が、expectedValue
引数で指定された値と一致しません。そのオブジェクトの現在の値が、GraphQL レスポンスのdata
セクションのerrors
フィールドで返されます。expectedVersion
を訂正して、このリクエストをもう一度試してみます。mutation deletePost { deletePost( id:123 expectedVersion: 1 ) { id author title content url ups downs version } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
deletePost
] を選択します。今回は、リクエストが成功し、Amazon 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 } } }
-
再度 [実行] を選択します。この呼び出しは成功しますが、そのポストが Amazon DynamoDB で既に削除されているため、今回は値が返されません。
{ "data": { "deletePost": null } }
allPost リゾルバーのセットアップ (Amazon DynamoDB スキャン)
これまでのところ、 APIは、参照する各投稿id
の がわかっている場合にのみ役立ちます。テーブル内のすべてのポストを返す新しいリゾルバーを追加してみましょう。
ミューテーションを追加するには
-
でAPI、スキーマタブを選択します。
-
[スキーマ] ペインの
Query
タイプを次のように変更して、新しいallPost
クエリを追加します。type Query { allPost(limit: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
-
新しい
PaginationPosts
型を追加します。type PaginatedPosts { posts: [Post!]! nextToken: String }
-
[Save Schema] を選択します。
-
右側の [リゾルバー] ペインで、
allPost
タイプから新しく作成されたQuery
フィールドを探し、[アタッチ] を選択します。次のコードを使用して新しいリゾルバーを作成します。import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { limit = 20, nextToken } = ctx.arguments; return ddb.scan({ limit, nextToken }); } export function response(ctx) { const { items: posts = [], nextToken } = ctx.result; return { posts, nextToken }; }
このリゾルバーのリクエストハンドラーには 2 つのオプション引数が必要です。
-
limit
- 1 回の呼び出しで返される項目の最大数を指定します。 -
nextToken
- 次の結果セットを取得するために使用されます (nextToken
の値がどこから来たのかは後で説明します)。
-
-
リゾルバーに加えた変更を保存します。
Scan
リクエストの詳細については、「Scan」リファレンスドキュメントを参照してください。
を呼び出しAPIてすべての投稿をスキャンする
これでリゾルバーが設定され、受信allPost
クエリを Amazon DynamoDB Scan
オペレーションに変換する AWS AppSync 方法について説明します。ユーザーは、テーブルをスキャンしてすべてのポストを取得できるようになりました。ただし、これまで使用してきたデータはすべて削除したため、これを試す前にテーブルにデータを入力しておく必要があります。
データを追加してクエリするには
-
でAPI、クエリタブを選択します。
-
以下のミューテーションを [クエリ] ペインに追加します。
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 } }
-
[実行] (オレンジ色の再生ボタン) を選択します。
-
では、テーブルをスキャンして、一度に 5 個の結果を返しましょう。以下のクエリをクエリペインに貼り付けます。
query allPost { allPost(limit: 5) { posts { id title } nextToken } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
allPost
] を選択します。最初の 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": "<token>" } } }
-
5 つの結果と
nextToken
を取得しました。このトークンを使用して、次の結果セットを取得できます。前回の結果セットからのallPost
を含めるように、nextToken
クエリを更新します。query allPost { allPost( limit: 5 nextToken: "<token>" ) { posts { id author } nextToken } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
allPost
] を選択します。残りの 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作成者リゾルバーの設定 (Amazon DynamoDB クエリ)
Amazon DynamoDB ですべてのポストをスキャンだけでなく、特定の作成者が作成したポストを取得するクエリを Amazon DynamoDB に対して実行することもできます。前の手順で作成した Amazon DynamoDB テーブルには、既に author-index
という GlobalSecondaryIndex
があるため、Amazon DynamoDB の Query
オペレーションでそれを使用して、特定の作成者が作成したすべてのポストを取得できます
クエリを追加するには
-
でAPI、スキーマタブを選択します。
-
[スキーマ] ペインの
Query
タイプを次のように変更して、新しいallPostsByAuthor
クエリを追加します。type Query { allPostsByAuthor(author: String!, limit: Int, nextToken: String): PaginatedPosts! allPost(limit: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
このクエリでは、
allPost
クエリで使用したのと同じPaginatedPosts
型を使用していることに注意してください。 -
[Save Schema] を選択します。
-
右側のリゾルバーペインで、
allPostsByAuthor
型の新しく作成されたQuery
フィールドを見つけて、[アタッチ] を選択します。以下のスニペットを使用してリゾルバーを作成します。import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { limit = 20, nextToken, author } = ctx.arguments; return ddb.query({ index: 'author-index', query: { author: { eq: author } }, limit, nextToken, }); } export function response(ctx) { const { items: posts = [], nextToken } = ctx.result; return { posts, nextToken }; }
allPost
リゾルバーと同様に、このリゾルバーには 2 つのオプション引数があります。-
limit
- 1 回の呼び出しで返される項目の最大数を指定します。 -
nextToken
- 次の結果セットを取得します (nextToken
の値は前回の呼び出しから取得できます)。
-
-
リゾルバーに加えた変更を保存します。
Query
リクエストの詳細については、「クエリ」リファレンスドキュメントを参照してください。
を呼び出しAPIて、作成者によるすべての投稿をクエリします。
リゾルバーがセットアップされたので、受信allPostsByAuthor
ミューテーションをauthor-index
インデックスに対して DynamoDB Query
オペレーションに変換する方法 AWS AppSync を理解します。ユーザーは、テーブルをクエリして、特定の作成者によるポストをすべて取得できます。
ただし、これまで使用していたポストはすべて同じ作成者だったため、それを行う前に、テーブルに投稿を追加しておきましょう。
データとクエリを追加するには
-
でAPI、クエリタブを選択します。
-
以下のミューテーションを [クエリ] ペインに追加します。
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 } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
addPost
] を選択します。 -
では、
Nadia
が作成したすべてのポストを返すクエリを実行しましょう。以下のクエリをクエリペインに貼り付けます。query allPostsByAuthor { allPostsByAuthor(author: "Nadia") { posts { id title } nextToken } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
allPostsByAuthor
] を選択します。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" limit: 5 ) { posts { id title } nextToken } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
allPostsByAuthor
] を選択します。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": "<token>" } } }
-
次のように、
nextToken
引数を、前回のクエリで返された値に更新します。query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" limit: 5 nextToken: "<token>" ) { posts { id title } nextToken } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
allPostsByAuthor
] を選択します。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
型は、フラットなキーと値のオブジェクトでした。 リゾルバーを使用して、セット型、リスト型、マップ型などの複雑なオブジェクトをモデル化することもできます。Post
型を更新して、タグを含めましょう。1 つのポストには、DynamoDB に文字列として保存されているタグを 0 個以上付けることができます。タグを追加および削除するミューテーションと、特定のタグが付いているポストをスキャンする新しいクエリもセットアップします。
データを設定するには
-
でAPI、スキーマタブを選択します。
-
[スキーマ] ペインの
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!, limit: Int, nextToken: String): PaginatedPosts! allPostsByAuthor(author: String!, limit: Int, nextToken: String): PaginatedPosts! allPost(limit: 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 Schema] を選択します。
-
右側のリゾルバーペインで、
allPostsByTag
型の新しく作成されたQuery
フィールドを見つけて、[アタッチ] を選択します。以下のスニペットを使用してリゾルバーを作成します。import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { limit = 20, nextToken, tag } = ctx.arguments; return ddb.scan({ limit, nextToken, filter: { tags: { contains: tag } } }); } export function response(ctx) { const { items: posts = [], nextToken } = ctx.result; return { posts, nextToken }; }
-
リゾルバーに加えた変更を保存します。
-
次に、以下のスニペットを使って
Mutation
フィールドaddTag
に対して同じ操作を行います。注記
DynamoDB ユーティリティは現在、セットオペレーションをサポートしていませんが、リクエストを自分で作成してセットを操作することはできます。
import { util } from '@aws-appsync/utils' export function request(ctx) { const { id, tag } = ctx.arguments const expressionValues = util.dynamodb.toMapValues({ ':plusOne': 1 }) expressionValues[':tags'] = util.dynamodb.toStringSet([tag]) return { operation: 'UpdateItem', key: util.dynamodb.toMapValues({ id }), update: { expression: `ADD tags :tags, version :plusOne`, expressionValues, }, } } export const response = (ctx) => ctx.result
-
リゾルバーに加えた変更を保存します。
-
以下のスニペットを使用して、これを
Mutation
フィールドでもう一度繰り返します。import { util } from '@aws-appsync/utils'; export function request(ctx) { const { id, tag } = ctx.arguments; const expressionValues = util.dynamodb.toMapValues({ ':plusOne': 1 }); expressionValues[':tags'] = util.dynamodb.toStringSet([tag]); return { operation: 'UpdateItem', key: util.dynamodb.toMapValues({ id }), update: { expression: `DELETE tags :tags ADD version :plusOne`, expressionValues, }, }; } export const response = (ctx) => ctx.resultexport
-
リゾルバーに加えた変更を保存します。
タグを操作するAPIには、 を呼び出します。
リゾルバーをセットアップしたので、受信する addTag
、、removeTag
および allPostsByTag
リクエストを DynamoDB UpdateItem
および Scan
オペレーションに変換する AWS AppSync 方法について説明します。それを試すには、前のステップで作成したポストのいずれかを選択します。例えば、Nadia
が作成したポストを使用しましょう。
タグを使用するには
-
でAPI、クエリタブを選択します。
-
以下のクエリをクエリペインに貼り付けます。
query allPostsByAuthor { allPostsByAuthor( author: "Nadia" ) { posts { id title } nextToken } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
allPostsByAuthor
] を選択します。 -
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 } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
addTag
] を選択します。ポストが新しいタグで更新されています。{ "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 } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
addTag
] を選択します。投稿が新しいタグで更新されています。{ "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 } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
removeTag
] を選択します。ポストが更新され、puppy
タグが削除されています。{ "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }
-
タグが付いているすべての投稿を検索することもできます。以下のクエリをクエリペインに貼り付けます。
query allPostsByTag { allPostsByTag(tag: "dog") { posts { id title tags } nextToken } }
-
[実行] (オレンジ色の再生ボタン) を選択し、[
allPostsByTag
] を選択します。次のようにdog
タグが付いているすべての投稿が返されます。{ "data": { "allPostsByTag": { "posts": [ { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } ], "nextToken": null } } }
結論
このチュートリアルでは、 AWS AppSync と GraphQL を使用して DynamoDB 内のPost
オブジェクトを操作APIできる を構築しました。
クリーンアップするには、コンソールAPIから AWS AppSync GraphQL を削除できます。
DynamoDB テーブルに関連付けられているロールを削除するには、[データソース] テーブルで [データソース]を選択し、[編集] をクリックします。[既存のロールを作成または使用する] の下にあるロールの値を書き留めます。IAM コンソールに移動してロールを削除します。
DynamoDB テーブルを削除するには、データソースリスト内のテーブルの名前をクリックします。これにより、DynamoDB コンソールに移動して、テーブルを削除できます。