はじめに
前回の記事で定義したGraphQLスキーマはAPIのインターフェースの定義でした。
このインターフェースを使ってAPIにアクセスがあった際に、データを保存する先のリソース(DataSource)の作成と連携の部分を設定していきます。
AWS AppSyncでは、Resolverを作成することで、DataSourceとGraphQLスキーマとの紐付けを行います。
リソース(DataSource)の作成
今回の例では、GraphQLスキーマに定義したTodo型からDynamoDBのテーブルを作成します。
まずは、コンソール画面から、「AWS AppSync > 作成したプロジェクト > Schema」を開き、画面右上の「Create Recources」をクリックします。
 
次の画面では、定義済みのGraphQLスキーマから使用する型を選択します。
今回はTodoを選択しました。
 
使用する型を選択すると、自動でテーブル名、テーブルの構成が入力されます。
今回は、idをプライマリキーとしました。
 
ここまでの項目を入力すると、画面最下部にテーブル定義を元に、自動で追加されるスキーマ定義のプレビューが表示されます。
最後に、「Create」ボタンをクリックすると、DynamoDBテーブルが作成されます。
 
Resolverの追加と修正
前の手順では、GraphQLスキーマから自動でDynamoDBとResolverのプロビジョニングを行いましたが、一部、定義元のスキーマと紐付いていない点があるので、追加・修正していきます。
getTodos
getTodosには、Resolverが紐付けられていないので、新規で追加します。
「Schema > Query > getTodos: [Todo]」の「Attach」をクリックします。
次の画面では、作成済みのDataSourceから紐付けるテーブルを選択します。
今回はTodoTabeを選択しました。
 
次に、リクエストのマッピングを行います。
「Paginated scan」のテンプレートをベースに、次のように変更しました。
{
    "version" : "2017-02-28",
    "operation" : "Scan"
}
レスポンスのマッピングは次のようになります。
$utils.toJson($context.result.items)
最後に、画面右下の「Save」をクリックしてResolverの設定を保存します。
getTodo
これは、自動で追加されたQueryです。
今回のToDoアプリでは、item一件ごとに取得するGetItem操作は不要なので、削除します。
allTodo
これは、自動で追加されたQueryです。
こちらは、getTodosと処理が重複するため削除します。
(ページネーション処理も自動で設定済みのようなので、こちらを使うのがよさそうですが...)
addTodo
自動で追加されたMutation、putTodoの内容をこちらに移行すれば良さそうです。
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "id": { "S" : "${context.arguments.id}"}
    },
    "attributeValues" : {
        "id": {  "S": "${context.arguments.id}" },
		"title": {  "S": "${context.arguments.title}" },
		"description": {  "S": "${context.arguments.description}" },
		"completed": {  "B": "${context.arguments.completed}" }
    }
}
$utils.toJson($context.result)
updateTodo
updateTodoには、Resolverが紐付けられていないので、新規で追加します。
getTodosで行った新規追加手順と同様に操作を行い、次のテンプレートを設定します。
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key": {
        "id": { "S" : "${context.arguments.id}"}
    },
    "update" : {
    	"expression" : "SET title = :title, description = :description, completed = :completed",
       	"expressionValues" : {
        	":title" : { "S": "${context.arguments.title}" },
          	":description" : { "S": "${context.arguments.description}" },
            ":completed" : { "BOOL": ${context.arguments.completed} }
       }
    }
}
$utils.toJson($context.result)
更新操作は、DynamoDBの更新式の指定が必須となっているようでうです。
deleteTodo
こちらは、自動でしっかりとマッピングされているので、そのまま使用します。
putTodo
これは、自動で追加されたMutationです。
こちらは、addTodoと処理が重複するため削除します。
以上で、Resolverの設定が終わりました。
APIの動作確認
作成したAPIの動作確認を行ってみます。
コンソール画面から、「AWS AppSync > 作成したプロジェクト > Queries」を開き、画面左側のエディターエリアにクエリを入力し「▶」をクリックしてクエリを実行します。
 
MutationとQueryそれぞれの項目を動作確認してみたいと思います。
addTodo
まずは、データを追加してみます。
mutation addTodo {
  addTodo(
    id: "0651ed86-9314-4267-9bcf-7143b785f173"
    title: "髪を切る"
    description: "来週までには"
    completed: false
  ) {
    id
    title
    description
    completed
  }
}
次のようなレスポンスが返ってくれば成功です。
{
  "data": {
    "addTodo": {
      "id": "0651ed86-9314-4267-9bcf-7143b785f173",
      "title": "髪を切る",
      "description": "来週までには",
      "completed": false
    }
  }
}
getTodos
事前に何件かデータを追加した状態で以下のクエリを実行します。
query {
  getTodos {
    id
    title
    description
    completed
  }
}
{
  "data": {
    "getTodos": [
      {
        "id": "f163372a-8b54-4da4-9237-911a64067517",
        "title": "豆腐を食べる",
        "description": "腐りそう",
        "completed": false
      },
      {
        "id": "0cbab86a-ad72-41b4-a63d-9ce3f9a7d552",
        "title": "Qiita書く",
        "description": "あと2本",
        "completed": false
      },
      {
        "id": "0651ed86-9314-4267-9bcf-7143b785f173",
        "title": "髪を切る",
        "description": "来週までには",
        "completed": false
      }
    ]
  }
}
updateTodo
mutation updateTodo {
  updateTodo(
    id: "0651ed86-9314-4267-9bcf-7143b785f173"
    title: "部屋を掃除する"
    description: "さらっと済ます"
    completed: false
  ) {
    id
    title
    description
    completed
  }
}
※ Responseは省略
deleteTodo
mutation deleteTodo {
  deleteTodo(
    id: "0651ed86-9314-4267-9bcf-7143b785f173"
  ) {
    id
    title
    description
    completed
  }
}
対象のitemのidを指定して、削除を行います。
※ Responseは省略
最後に
今回は、定義したGraphQLスキーマから自動でリソースを作成しましたが、AppSyncのコンソールからは、全て手動でリソースを用意することもできます。必要に応じて使い分けると良さそうです。
次回は、作成したGraphQL APIと連携するReactフロントエンドの実装を行っていく予定です。
参考
Attaching a Data Source -AWS AppSync
Provision from Schema -AWS AppSync
Resolver Mapping Template Reference for DynamoDB -AWS AppSync