

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

# GraphQL API の構築 (空の API またはインポートされた API)
<a name="blank-import-api"></a>

空白のテンプレートから GraphQL API を作成する前に、GraphQL に関する概念を確認しておくと役に立ちます。GraphQL API には次の 3 つの基本的なコンポーネントがあります。

1. **スキーマ**は、データの形状と定義が含まれているファイルです。GraphQL サービスに対してクライアントによってリクエストが実行されるとき、返されるデータはスキーマの仕様に従います。詳細については、「[GraphQL スキーマ](schema-components.md#aws-appsync-schema-components)」を参照してください。

1. **データソース**はスキーマにアタッチされます。リクエストが実行されると、ここでデータが取得され、変更されます。詳細については、「[ データソース](data-source-components.md#aws-appsync-data-source-components)」を参照してください。

1. **リゾルバー**はスキーマとデータソースの間に存在します。リクエストが実行されると、リゾルバーはソースからデータに対してオペレーションを実行し、結果をレスポンスとして返します。詳細については、「[ リゾルバー](resolver-components.md#aws-appsync-resolver-components)」を参照してください。

![\[GraphQL API architecture showing schema, resolvers, and data sources connected via AppSync.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/appsync-architecture-graphql-api.png)


AWS AppSync は、スキーマとリゾルバーのコードを作成、編集、保存できるようにすることで APIs を管理します。データソースは、データベース、DynamoDB テーブル、Lambda 関数などの外部リポジトリから取得されます。 AWS サービスを使用してデータを保存する場合、またはデータを保存することを計画している場合、 は AWS アカウントから GraphQL APIs にデータを関連付けたときに、ほぼシームレスなエクスペリエンス AWS AppSync を提供します。

次のセクションでは、 AWS AppSync サービスを使用してこれらの各コンポーネントを作成する方法について説明します。

**Topics**
+ [GraphQL スキーマの設計](designing-your-schema.md)
+ [データソースを追加する](attaching-a-data-source.md)
+ [AWS AppSync リゾルバーの設定](resolver-config-overview.md)
+ [CDK での API の使用](using-your-api.md)

# GraphQL スキーマの設計
<a name="designing-your-schema"></a>

GraphQL スキーマは、あらゆる GraphQL サーバー実装の基盤です。各 GraphQL API は、リクエストからのデータがどのように入力されるかを記述するタイプとフィールドを含む**単一の**スキーマによって定義されます。API を経由するデータフローと実行される操作は、スキーマと照合して検証する必要があります。

[GraphQL タイプシステム](https://graphql.org/learn/schema/#type-system)は、GraphQL サーバーの機能を記述し、クエリが有効であることを判別するために使用されます。サーバーのタイプシステムはしばしばそのサーバーのスキーマと呼ばれ、さまざまなオブジェクトタイプ、スカラー型、入力型などで構成されます。GraphQL は宣言型であると同時に厳密に型付けされています。つまり、型はランタイムに明確に定義され、指定されたものだけを返します。

AWS AppSync では、GraphQL スキーマを定義および設定できます。次のセクションでは、 AWS AppSyncのサービスを使用して GraphQL スキーマを最初から作成する方法について説明します。

## GraphQL スキーマの構造化
<a name="schema-structure"></a>

**ヒント**  
続ける前に「[スキーマ](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html)」セクションを確認することをおすすめします。

GraphQL は API サービスを実装するための強力なツールです。[GraphQL のウェブサイト](https://graphql.org/)によると、GraphQL は以下の通りです。

「*GraphQL は API 用のクエリ言語であり、既存のデータでそれらのクエリを実行するためのランタイムです。GraphQL は、API 内のデータを完全かつわかりやすく説明し、クライアントが必要としているものだけを尋ねることができるようにし、時間の経過とともに API を進化させやすくし、強力な開発者ツールを可能にします*」

このセクションでは、GraphQL 実装の最初の部分であるスキーマについて説明します。上の引用を使用すると、スキーマは「API 内のデータを完全かつわかりやすく説明する」役割を果たします。言い換えると、GraphQL スキーマは、サービスのデータ、操作、およびそれらの間の関係をテキストで表現したものです。スキーマは、GraphQL サービス実装の主要なエントリポイントと見なされます。当然のことながら、多くの場合、プロジェクトで最初に作成するものの 1 つです。次に進む前に「[スキーマ](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html)」セクションを確認することをおすすめします。

「[スキーマ](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html)」セクションを引用すると、GraphQL スキーマは*スキーマ定義言語* (SDL) で記述されています。SDL は、構造が確立された型とフィールドで構成されています。
+ **タイプ**: タイプとは、GraphQL がデータの形状と動作を定義する方法です。GraphQL は、このセクションの後半で説明する多数の型をサポートしています。スキーマで定義されている各タイプには、独自のスコープが含まれます。スコープ内には、GraphQL サービスで使用される値またはロジックを含むことができる 1 つ以上のフィールドがあります。型にはさまざまな役割がありますが、最も一般的なのはオブジェクトまたはスカラー (プリミティブ値型) です。
+ **フィールド**: フィールドはタイプのスコープ内に存在し、GraphQL サービスから要求された値を保持します。これらは他のプログラミング言語の変数とよく似ています。フィールドで定義するデータの形状によって、リクエスト/レスポンス操作におけるデータの構造が決まります。これにより、開発者はサービスのバックエンドがどのように実装されているかを知らなくても、何が返されるかを予測できます。

最も単純なスキーマには、次の 3 つの異なるデータカテゴリが含まれます。

1. **スキーマルート**: ルートはスキーマのエントリポイントを定義します。データの追加、削除、変更などの操作を行うフィールドを指します。

1. **タイプ**: これらはデータの形状を表すために使用される基本タイプです。これらは概して、定義された特性を持つ何かのオブジェクト、または抽象的な表現と考えることができます。例えば、データベース内の人を表す `Person` オブジェクトを作成できます。各個人の特性はフィールド `Person` として内部で定義されます。名前、年齢、職業、住所など何でも構いません。

1. **特殊オブジェクトタイプ**: スキーマ内の操作の動作を定義するタイプです。特殊オブジェクトタイプはそれぞれ、スキーマごとに 1 回定義されます。これらは最初にスキーマのルートに配置され、次にスキーマ本体で定義されます。特別なオブジェクトタイプの各フィールドは、リゾルバーによって実装される単一の操作を定義します。

これを大局的に見ると、著者とその著者が書いた本を保存するサービスを作成していると想像してみてください。各著者には名前と執筆した本の配列があります。各本には名前と関連する著者のリストがあります。また、本や著者を追加したり、検索したりできる機能も必要です。この関係を単純な UML 表現で表現すると、次のようになります。

![\[UML diagram showing Author and Book classes with attributes and methods, linked by association.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/GraphQL-UML-1.png)


GraphQL では、`Author` および `Book` エンティティとはスキーマ内の 2 つの異なるオブジェクトタイプを表します。

```
type Author {
}

type Book {
}
```

`Author` には `authorName` と `Books` が含まれ、`Book` には `bookName` と`Authors` が含まれます。これらはタイプのスコープ内のフィールドとして表すことができます。

```
type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}
```

ご覧のとおり、型表現は図と非常に似ています。しかし、メソッドは少し難しいところです。これらは、いくつかの特殊なオブジェクトタイプのいずれかにフィールドとして配置されます。特殊なオブジェクト分類は、その動作によって異なります。GraphQL には、クエリ、ミューテーション、およびサブスクリプションの 3 つの基本的な特殊オブジェクトタイプがあります。[特別なオブジェクト](https://docs.aws.amazon.com//appsync/latest/devguide/graphql-types.html#special-object-components)の詳細については、 を参照してください。

`getAuthor`と`getBook`はどちらもデータを要求しているため、`Query` の特別なオブジェクトタイプに配置されます。

```
type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}
```

オペレーションはクエリにリンクされ、クエリ自体もスキーマにリンクされます。スキーマルートを追加すると、特別なオブジェクトタイプ (この場合は `Query`) がエントリポイントの 1 つとして定義されます。これは `schema` キーワードを使用して行うことがＤけいます。

```
schema {
  query: Query
}

type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}
```

最後の 2 つの方法を見てみると、`addAuthor` と `addBook` はデータベースにデータを追加しているので、これらは`Mutation` の特別なオブジェクトタイプで定義されます。ただし、[タイプ](https://docs.aws.amazon.com/appsync/latest/devguide/graphql-types.html#input-components)ページを見ると、オブジェクトを直接参照する入力は厳密には出力タイプなので、許可されていないこともわかります。この場合、`Author` または `Book` は使用できないため、同じフィールドを持つ入力タイプを作成する必要があります。この例では、`AuthorInput` と `BookInput` を追加しましたが、どちらもそれぞれのタイプの同じフィールドを受け入れます。次に、入力をパラメータとして使用してミューテーションを作成します。

```
schema {
  query: Query
  mutation: Mutation
}

type Author {
  authorName: String
  Books: [Book]
}

input AuthorInput {
  authorName: String
  Books: [BookInput]
}

type Book {
  bookName: String
  Authors: [Author]
}

input BookInput {
  bookName: String
  Authors: [AuthorInput]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}

type Mutation {
  addAuthor(input: [BookInput]): Author
  addBook(input: [AuthorInput]): Book
}
```

先ほど行ったことを振り返ってみましょう。

1. エンティティを表すための `Book` および `Author` タイプを含むスキーマを作成しました。

1. エンティティの特徴を含むフィールドを追加しました。

1. この情報をデータベースから取得するクエリを追加しました。

1. データベース内のデータを操作するミューテーションを追加しました。

1. GraphQL のルールに準拠するため、ミューテーション内のオブジェクトパラメータを置き換える入力タイプを追加しました。

1. GraphQL 実装がルートタイプの場所を理解できるように、クエリとミューテーションをルートスキーマに追加しました。

ご覧のとおり、スキーマを作成するプロセスには、一般的なデータモデリング (特にデータベースモデリング) から多くの概念が取り入れられています。スキーマはソースからのデータの形に合っていると考えることができます。リゾルバーが実装するモデルとしても機能します。以下のセクションでは、さまざまな AWSバックアップツールとサービスを使用してスキーマを作成する方法について説明します。

**注記**  
以下のセクションの例は、実際のアプリケーションで実行するためのものではありません。これらの説明は、ユーザーが独自のアプリケーションを構築できるようにコマンドを紹介することのみを目的としています。

## スキーマの作成
<a name="creating-schema"></a>

スキーマは というファイルにあります`schema.graphql`。 AWS AppSync を使用すると、ユーザーはさまざまな方法を使用して GraphQL APIs の新しいスキーマを作成できます。この例では、空の API と空白のスキーマを作成します。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

   1. **ダッシュボード**で、**[API の作成]** を選択します。

   1. **[API オプション]** で、**[GraphQL API]**、**[最初から設計]**、**[次へ]** の順に選択します。

      1. **API 名**では、あらかじめ入力されている名前をアプリケーションに必要な名前に変更します。

      1. **連絡先情報**については、API のマネージャーを特定する連絡先を入力できます。これはオプションのフィールドです。

      1. **[Private API 設定]** で、プライベート API 機能を有効にできます。プライベート API には、設定された VPC エンドポイント (VPCE) からのみアクセスできます。詳細については、「[プライベート DNS](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html)」を参照してください。

         この例では、この機能を有効にすることはお勧めしません。**[次へ]** 選択して入力を確認します。

   1. **[GraphQL タイプを作成]** では、データソースとして使用する DynamoDB テーブルを作成するか、この作業をスキップして後で作成するかを選択できます。

      この例では、**[GraphQL リソースを後で作成]** を選択します。リソースは別のセクションで作成します。

   1. 入力内容を確認し、**[API を作成]** を選択します。

1. 特定の API のダッシュボードが表示されます。API の名前がダッシュボードの上部にあるのでわかります。そうでない場合は、**サイドバー**で **[API]** を選択し、**API ダッシュボード**で API を選択できます。

   1. API 名の下の**サイドバー**で、**[スキーマ]** を選択します。

1. **スキーマエディタでは**、ファイルを設定できます。`schema.graphql`ファイルは空でも、モデルから生成されたタイプで埋め込まれていてもかまいません。右側には、リゾルバーをスキーマフィールドにアタッチするための **[リゾルバー]** セクションがあります。このセクションではリゾルバーについては説明しません。

------
#### [ CLI ]

**注記**  
CLI を使用するときは、サービス内のリソースにアクセスして作成するための正しい権限を持っていることを確認してください。サービスにアクセスする必要がある管理者以外のユーザーには、[最小特権](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)ポリシーを設定するとよいでしょう。 AWS AppSync ポリシーの詳細については、「 の [Identity and Access Management AWS AppSync](https://docs.aws.amazon.com//appsync/latest/devguide/security-iam.html)」を参照してください。  
まだの場合は、コンソール版最初に読むことをお勧めします。

1. まだをインストールしてしていない場合は、 AWS CLI を[インストール](https://docs.aws.amazon.com//cli/latest/userguide/cli-chap-getting-started.html)して設定します。

1. [https://docs.aws.amazon.com/cli/latest/reference/appsync/create-graphql-api.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-graphql-api.html)コマンドを実行して GraphQL API オブジェクトを作成します。

   この特定のコマンドには、次の 2 つのパラメータを入力する必要があります。

   1. API の `name` です。

   1. `authentication-type`、または API へのアクセスに使用される認証情報の種類 (IAM、OIDC など)。
**注記**  
`Region` など、その他のパラメータは設定する必要がありますが、通常はデフォルトで CLI 設定値になります。

   コマンドの例は、次のようになります。

   ```
   aws appsync create-graphql-api --name testAPI123 --authentication-type API_KEY
   ```

   出力は CLI に返されます。例を示します。

   ```
   {
       "graphqlApi": {
           "xrayEnabled": false,
           "name": "testAPI123",
           "authenticationType": "API_KEY",
           "tags": {},
           "apiId": "abcdefghijklmnopqrstuvwxyz",
           "uris": {
               "GRAPHQL": "https://zyxwvutsrqponmlkjihgfedcba.appsync-api.us-west-2.amazonaws.com/graphql",
               "REALTIME": "wss://zyxwvutsrqponmlkjihgfedcba.appsync-realtime-api.us-west-2.amazonaws.com/graphql"
           },
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz"
       }
   }
   ```

1. 
**注記**  
これはオプションコマンドで、既存のスキーマを取得し、base-64 BLOB を使用して AWS AppSync サービスにアップロードします。この例では、このコマンドは使用しません。

   [https://docs.aws.amazon.com/cli/latest/reference/appsync/start-schema-creation.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/start-schema-creation.html) コマンドを実行します。

   この特定のコマンドには、次の 2 つのパラメータを入力する必要があります。

   1. `api-id` は前のステップからのものです。

   1. スキーマ `definition`は base-64 でエンコードされたバイナリブロブです。

   コマンドの例は、次のようになります。

   ```
    aws appsync start-schema-creation --api-id abcdefghijklmnopqrstuvwxyz --definition "aa1111aa-123b-2bb2-c321-12hgg76cc33v"
   ```

   次のような出力が返されます。

   ```
   {
       "status": "PROCESSING"
   }
   ```

   このコマンドは処理後の最終出力を返しません。結果を確認するには別のコマンド [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/get-schema-creation-status.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/get-schema-creation-status.html) を使用する必要があります。この 2 つのコマンドは非同期なので、スキーマの作成中でも出力ステータスを確認できることに注意してください。

------
#### [ CDK ]

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/home.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
以下の手順では、特定のリソースを追加するために使用するスニペットの一般的な例のみを示しています。これは本番稼働用コードで機能するソリューションとなることを**意図したものではありません**。また、動作するアプリが既にあることを前提としています。

1. CDK の開始点は少し異なります。理想的には、`schema.graphql` ファイルはすでに作成されているはずです。必要なのは、`.graphql` ファイル拡張子が付いた新しいファイルを作成することだけです。空のリストを指定できます。

1. 一般的には、使用しているサービスにインポートディレクティブを追加しなければならない場合があります。たとえば、次の形式に従います。

   ```
   import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
   import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
   ```

   GraphQL API を追加するには、スタックファイルで AWS AppSync サービスをインポートする必要があります。

   ```
   import * as appsync from 'aws-cdk-lib/aws-appsync';
   ```
**注記**  
つまり、`appsync` キーワードでサービス全体をインポートすることになります。アプリでこれを使用するには、 AWS AppSync コンストラクトは の形式を使用します`appsync.construct_name`。例えば、GraphQL API を作りたいなら、`new appsync.GraphqlApi(args_go_here)` と言うでしょう。次のステップはこれを描写しています。

1. 最も基本的な GraphQL API には、API 用の `name` と `schema` パスが含まれます。

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     name: 'name_of_API_in_console',
     schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema_name.graphql')),
   });
   ```
**注記**  
このスニペットが何をするのか見てみましょう。`api` の範囲内では、`appsync.GraphqlApi(scope: Construct, id: string, props: GraphqlApiProps)` を呼び出して新しい GraphQL API を作成しています。スコープは `this` で、現在のオブジェクトを参照します。ID は *API\$1ID* で、作成 CloudFormation 時に の GraphQL API のリソース名になります。`GraphqlApiProps` には、GraphQL API の `name` と `schema` が含まれています。`schema` は、`.graphql` ファイル (*schema\$1name.graphql*) の絶対パス (`__dirname`) を検索してスキーマ (`SchemaFile.fromAsset`) を生成します。実際のシナリオでは、スキーマファイルはおそらく CDK アプリ内にあるでしょう。  
GraphQL API に加えた変更を使用するには、アプリを再デプロイする必要があります。

------

## スキーマへのタイプの追加
<a name="adding-schema-types"></a>

スキーマを追加したので、入力タイプと出力タイプの両方を追加し始めることができます。ここで説明する型は実際のコードでは使用しないでください。これらはプロセスの理解に役立つ例に過ぎません。

まず、オブジェクトタイプを作成します。実際のコードでは、これらのタイプから始める必要はありません。GraphQL の規則と構文に従っていれば、いつでも好きなタイプを作ることができます。

**注記**  
次のいくつかのセクションでは**スキーマエディター**を使用するので、これを開いたままにしておきます。

------
#### [ Console ]
+ オブジェクトタイプは、`type` キーワードとタイプ名を使用して作成できます。

  ```
  type Type_Name_Goes_Here {}
  ```

  タイプのスコープ内には、オブジェクトの特性を表すフィールドを追加できます。

  ```
  type Type_Name_Goes_Here {
    # Add fields here
  }
  ```

  例を示します。

  ```
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  ```
**注記**  
このステップでは、必須の `id` フィールドを `ID` として格納し、`title` フィールドを `String` として格納し、`date` フィールドを `AWSDateTime` として格納する汎用オブジェクトタイプを追加しました。タイプとフィールド、およびその機能の一覧については、「[スキーマ](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html)」を参照してください。スカラーの一覧とその機能については、[タイプのリファレンス](https://docs.aws.amazon.com/appsync/latest/devguide/type-reference.html)を参照してください。

------
#### [ CLI ]

**注記**  
まだの場合は、コンソール版最初に読むことをお勧めします。
+ オブジェクトタイプは [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html) コマンドを実行して作成できます。

  この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

  1. API の `api-id` です。

  1. `definition`、またはタイプのコンテンツです。コンソールの例では、次のようになっていました。

     ```
     type Obj_Type_1 {
       id: ID!
       title: String
       date: AWSDateTime
     }
     ```

  1. 入力の `format` です。この例では、`SDL` を使用します。

  コマンドの例は、次のようになります。

  ```
  aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Obj_Type_1{id: ID! title: String date: AWSDateTime}" --format SDL
  ```

  出力は CLI に返されます。例を示します。

  ```
  {
      "type": {
          "definition": "type Obj_Type_1{id: ID! title: String date: AWSDateTime}",
          "name": "Obj_Type_1",
          "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Obj_Type_1",
          "format": "SDL"
      }
  }
  ```
**注記**  
このステップでは、必須の `id` フィールドを `ID` として格納し、`title` フィールドを `String` として格納し、`date` フィールドを `AWSDateTime` として格納する汎用オブジェクトタイプを追加しました。タイプとフィールド、およびその機能の一覧については、「[スキーマ](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html)」を参照してください。スカラーの一覧とその機能については、[タイプのリファレンス](https://docs.aws.amazon.com/appsync/latest/devguide/type-reference.html)を参照してください。  
さらにお気づきかもしれませんが、定義を直接入力しても、小さいタイプでは有効ですが、大きい型や複数のタイプを追加することはできません。`.graphql` ファイルにすべてを追加し、[それを入力として渡す](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-file.html)こともできます。

------
#### [ CDK ]

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/home.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
以下の手順では、特定のリソースを追加するために使用するスニペットの一般的な例のみを示しています。これは本番稼働用コードで機能するソリューションとなることを**意図したものではありません**。また、動作するアプリが既にあることを前提としています。

タイプを追加するには、`.graphql` ファイルに追加する必要があります。例えば、コンソールの例は次のとおりです。

```
type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}
```

他のファイルと同様に、タイプをスキーマに直接追加できます。

**注記**  
GraphQL API に加えた変更を使用するには、アプリを再デプロイする必要があります。

------

[オブジェクトタイプ](https://graphql.org/learn/schema/#object-types-and-fields)には、文字列や整数などの[スカラー型](https://graphql.org/learn/schema/#scalar-types)であるフィールドがあります。 AWS AppSync では、基本 GraphQL スカラー`AWSDateTime`に加えて、 などの拡張スカラー型を使用することもできます。また、名前が感嘆符で終わっているフィールドは必須フィールドです。

`ID` スカラー型は、`String` または `Int` のいずれかである一意の識別子です。これらはリゾルバーのマッピングテンプレートで自動割り当てを制御できます。

`Query` のような特別なオブジェクトタイプと上記の例のような「通常の」オブジェクトタイプでは、どちらも`type` キーワードを使用し、オブジェクトと見なされるという点で類似点があります。ただし、特殊オブジェクトタイプ (`Query`、`Mutation`、および`Subscription`) は API のエントリポイントとして公開されるため、動作が大きく異なります。また、データというよりは、オペレーションのシェーピングに関するものでもあります。詳細については、「[The Query and Mutation types](https://graphql.org/learn/schema/#the-query-and-mutation-types)」を参照してください。

特殊なオブジェクトタイプについて言えば、次のステップは、1 つまたは複数のオブジェクトタイプを追加して、シェーピングされたデータに対して操作を実行することです。実際のシナリオでは、すべての GraphQL スキーマには、データをリクエストするためのルートクエリタイプが少なくとも必要です。クエリは、GraphQL サーバーのエントリポイント (またはエンドポイント) の 1 つと考えることができます。例としてクエリを追加してみましょう。

------
#### [ Console ]
+ クエリを作成するには、他のタイプと同様にスキーマファイルに追加するだけです。クエリには、次のような `Query` タイプとルート内のエントリが必要です。

  ```
  schema {
    query: Name_of_Query
  }
  
  type Name_of_Query {
    # Add field operation here
  }
  ```

  プロダクション環境の *Name\$1of\$1Query* は、ほとんどの場合、単純に `Query` と呼ばれることに注意してください。この値のままにしておくことをお勧めします。クエリタイプ内にはフィールドを追加できます。各フィールドはリクエスト内でオペレーションを実行します。その結果、すべてではないにしても、ほとんどのフィールドがリゾルバーにアタッチされます。ただし、このセクションではその点については触れません。フィールドのオペレーションの形式については、次のようになります。

  ```
  Name_of_Query(params): Return_Type # version with params
  Name_of_Query: Return_Type # version without params
  ```

  例を示します。

  ```
  schema {
    query: Query
  }
  
  type Query {
    getObj: [Obj_Type_1]
  }
  
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  ```
**注記**  
このステップでは、`Query` タイプを追加して `schema` ルートで定義しました。`Query` タイプは、`Obj_Type_1` オブジェクトのリストを返す `getObj` フィールドを定義しました。`Obj_Type_1` が前のステップのオブジェクトであることに注意してください。プロダクションコードでは、フィールド操作は通常、`Obj_Type_1` のようなオブジェクトによって形成されたデータを処理します。さらに、`getObj` のようなフィールドには通常、ビジネスロジックを実行するリゾルバーがあります。これについては別のセクションで説明します。  
追加の注意点として、 はエクスポート中にスキーマルート AWS AppSync を自動的に追加するため、技術的にはスキーマに直接追加する必要はありません。弊社のサービスは重複するスキーマを自動的に処理します。ベストプラクティスとしてここに追加しています。

------
#### [ CLI ]

**注記**  
まだの場合は、コンソール版最初に読むことをお勧めします。

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html) コマンドを実行して `query` 定義付きの `schema` ルートを作成します。

   この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

   1. API の `api-id` です。

   1. `definition`、またはタイプのコンテンツです。コンソールの例では、次のようになっていました。

      ```
      schema {
        query: Query
      }
      ```

   1. 入力の `format` です。この例では、`SDL` を使用します。

   コマンドの例は、次のようになります。

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "schema {query: Query}" --format SDL
   ```

   出力は CLI に返されます。例を示します。

   ```
   {
       "type": {
           "definition": "schema {query: Query}",
           "name": "schema",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```
**注記**  
`create-type` コマンドに正しく入力しなかった場合は、[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html) コマンドを実行することでスキーマルート (またはスキーマ内の任意のタイプ) を更新できることに注意してください。この例では、`subscription` 定義を含むようにスキーマルートを一時的に変更します。  
この特定のコマンドでは、いくつかのパラメータを入力する必要があります。  
API の `api-id` です。
タイプの `type-name`。コンソールの例では、これは `schema` でした。
`definition`、またはタイプのコンテンツです。コンソールの例では、次のようになっていました。  

      ```
      schema {
        query: Query
      }
      ```
`subscription` を追加した後のスキーマは次のようになります。  

      ```
      schema {
        query: Query
        subscription: Subscription
      }
      ```
入力の `format` です。この例では、`SDL` を使用します。
コマンドの例は、次のようになります。  

   ```
   aws appsync update-type --api-id abcdefghijklmnopqrstuvwxyz --type-name schema --definition "schema {query: Query subscription: Subscription}" --format SDL
   ```
出力は CLI に返されます。例を示します。  

   ```
   {
       "type": {
           "definition": "schema {query: Query subscription: Subscription}",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```
この例でも、フォーマット済みのファイルを追加しても問題ありません。

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html) コマンドを実行して `Query` タイプを作成します。

   この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

   1. API の `api-id` です。

   1. `definition`、またはタイプのコンテンツです。コンソールの例では、次のようになっていました。

      ```
      type Query {
        getObj: [Obj_Type_1]
      }
      ```

   1. 入力の `format` です。この例では、`SDL` を使用します。

   コマンドの例は、次のようになります。

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Query {getObj: [Obj_Type_1]}" --format SDL
   ```

   出力は CLI に返されます。例を示します。

   ```
   {
       "type": {
           "definition": "Query {getObj: [Obj_Type_1]}",
           "name": "Query",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Query",
           "format": "SDL"
       }
   }
   ```
**注記**  
このステップでは、`Query` タイプを追加して `schema` ルートで定義しました。`Query` タイプは、`Obj_Type_1` オブジェクトのリストを返す `getObj` フィールドを定義しました。  
`schema` ルートコードでは`query: Query`、`query:` 部分はクエリがスキーマで定義されたことを示し、`Query` 部分は実際の特別なオブジェクト名を示します。

------
#### [ CDK ]

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/home.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
以下の手順では、特定のリソースを追加するために使用するスニペットの一般的な例のみを示しています。これは本番稼働用コードで機能するソリューションとなることを**意図したものではありません**。また、動作するアプリが既にあることを前提としています。

クエリとスキーマルートを `.graphql` ファイルに追加する必要があります。この例は以下の例のようになっていますが、実際のスキーマコードに置き換える必要があります。

```
schema {
  query: Query
}

type Query {
  getObj: [Obj_Type_1]
}

type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}
```

他のファイルと同様に、タイプをスキーマに直接追加できます。

**注記**  
スキーマルートの更新は任意です。ベストプラクティスとして、この例に追加しました。  
GraphQL API に加えた変更を使用するには、アプリを再デプロイする必要があります。

------

オブジェクトと特殊オブジェクト (クエリ) の両方を作成する例を見てきました。また、これらを相互に接続してデータや操作を記述する方法についても説明しました。データ記述と 1 つ以上のクエリのみを含むスキーマを作成できます。ただし、データソースにデータを追加する操作をもう 1 つ追加したいと考えています。データを変更する `Mutation` と呼ばれる特別なオブジェクトタイプを追加します。

------
#### [ Console ]
+ ミューテーションは`Mutation`と呼ばれます。`Query` と同様に、`Mutation` 内部のフィールド操作は操作を記述し、リゾルバーにアタッチされます。また、これは特殊なオブジェクトタイプなので、`schema` ルートで定義する必要があることにも注意してください。ミューテーションの例を示します。

  ```
  schema {
    mutation: Name_of_Mutation
  }
  
  type Name_of_Mutation {
    # Add field operation here
  }
  ```

  一般的なミューテーションは、クエリのようにルートにリストされます。ミューテーションは `type` キーワードと名前を使って定義されます。通常は *Name\$1of\$1Mutation* が`Mutation`と呼ばれるので、そのままにしておくことをおすすめします。各フィールドはオペレーションも実行します。フィールドのオペレーションの形式については、次のようになります。

  ```
  Name_of_Mutation(params): Return_Type # version with params
  Name_of_Mutation: Return_Type # version without params
  ```

  例を示します。

  ```
  schema {
    query: Query
    mutation: Mutation
  }
  
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  
  type Query {
    getObj: [Obj_Type_1]
  }
  
  type Mutation {
    addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
  }
  ```
**注記**  
このステップでは、`addObj` フィールドのある `Mutation` タイプを追加しました。このフィールドの機能をまとめてみましょう。  

  ```
  addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
  ```
`addObj` では `Obj_Type_1` オブジェクトを使用してオペレーションを実行しています。これはフィールドがあるから明らかですが、構文では `: Obj_Type_1` 戻り値のタイプでもそれが証明されています。`addObj` 内部では、`Obj_Type_1` オブジェクトの`id`、`title`、`date` フィールドをパラメータとして受け付けています。ご覧のとおり、これはメソッド宣言によく似ています。ただし、メソッドの動作についてはまだ説明していません。前述のように、スキーマはデータとオペレーションの内容を定義するためだけのもので、オペレーションの方法を定義するものではありません。実際のビジネスロジックの実装は、後で最初のリゾルバーを作成するときに実装します。  
スキーマが完成したら、それを `schema.graphql` ファイルとしてエクスポートするオプションがあります。**スキーマエディター**で **[スキーマをエクスポート]** を選択すると、サポートされている形式でファイルをダウンロードできます。  
追加の注意点として、 はエクスポート中にスキーマルート AWS AppSync を自動的に追加するため、技術的にはスキーマに直接追加する必要はありません。弊社のサービスは重複するスキーマを自動的に処理します。ベストプラクティスとしてここに追加しています。

------
#### [ CLI ]

**注記**  
まだの場合は、コンソール版最初に読むことをお勧めします。

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html) コマンドを実行してルートスキーマを更新します。

   この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

   1. API の `api-id` です。

   1. タイプの `type-name`。コンソールの例では、これは `schema` でした。

   1. `definition`、またはタイプのコンテンツです。コンソールの例では、次のようになっていました。

      ```
      schema {
        query: Query
        mutation: Mutation
      }
      ```

   1. 入力の `format` です。この例では、`SDL` を使用します。

   コマンドの例は、次のようになります。

   ```
   aws appsync update-type --api-id abcdefghijklmnopqrstuvwxyz --type-name schema --definition "schema {query: Query mutation: Mutation}" --format SDL
   ```

   出力は CLI に返されます。例を示します。

   ```
   {
       "type": {
           "definition": "schema {query: Query mutation: Mutation}",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html) コマンドを実行して `Mutation` タイプを作成します。

   この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

   1. API の `api-id` です。

   1. `definition`、またはタイプのコンテンツです。コンソールの例では、次のようになっていました。

      ```
      type Mutation {
        addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
      }
      ```

   1. 入力の `format` です。この例では、`SDL` を使用します。

   コマンドの例は、次のようになります。

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Mutation {addObj(id: ID! title: String date: AWSDateTime): Obj_Type_1}" --format SDL
   ```

   出力は CLI に返されます。例を示します。

   ```
   {
       "type": {
           "definition": "type Mutation {addObj(id: ID! title: String date: AWSDateTime): Obj_Type_1}",
           "name": "Mutation",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation",
           "format": "SDL"
       }
   }
   ```

------
#### [ CDK ]

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/home.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
以下の手順では、特定のリソースを追加するために使用するスニペットの一般的な例のみを示しています。これは本番稼働用コードで機能するソリューションとなることを**意図したものではありません**。また、動作するアプリが既にあることを前提としています。

クエリとスキーマルートを `.graphql` ファイルに追加する必要があります。この例は以下の例のようになっていますが、実際のスキーマコードに置き換える必要があります。

```
schema {
  query: Query
  mutation: Mutation
}

type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}

type Query {
  getObj: [Obj_Type_1]
}

type Mutation {
  addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
}
```

**注記**  
スキーマルートの更新は任意です。ベストプラクティスとして、この例に追加しました。  
GraphQL API に加えた変更を使用するには、アプリを再デプロイする必要があります。

------

## その他の考慮事項 - 列挙型をステータスとして使用する
<a name="optional-consideration-enums"></a>

これで、基本的なスキーマの作り方がわかりました。しかし、スキーマの機能を高めるために追加できることはたくさんあります。アプリケーションによく見られることの 1 つは、列挙型をステータスとして使用することです。列挙型を使用すると、呼び出し時に値のセットから特定の値を強制的に選択させることができます。これは、長期間にわたって大幅に変化することはないとわかっている場合に便利です。仮説的に言えば、レスポンスにステータスコードまたは文字列を返す列挙型を追加できるかもしれません。

例として、ユーザーの投稿データをバックエンドに保存するソーシャルメディアアプリを作っているとしましょう。このスキーマには、個々の投稿のデータを表す `Post` タイプが含まれています。

```
type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}
```

私たちの `Post` には一意の `id`、投稿 `title`、投稿の `date` と、アプリによって処理された投稿の状態を表す `PostStatus` と呼ばれるという列挙型が含まれます。今回の操作では、すべての投稿データを返すクエリを用意します。

```
type Query {
  getPosts: [Post]
}
```

また、データソースに投稿を追加するミューテーションもあります。

```
type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}
```

スキーマを見ると、`PostStatus` 列挙型には複数のステータスがある可能性があります。`success` (投稿は正常に処理されました)、`pending` (投稿は処理中)、`error` (投稿は処理できません) という 3 つの基本的な状態が必要な場合があります。列挙型を追加するには、次のようにします。

```
enum PostStatus {
  success
  pending
  error
}
```

完全なスキーマは次のようになります。

```
schema {
  query: Query
  mutation: Mutation
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}

type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}

type Query {
  getPosts: [Post]
}

enum PostStatus {  
  success
  pending
  error
}
```

ユーザーがアプリケーションに `Post` を追加すると、そのデータを処理する `addPost` オペレーションが呼び出されます。`addPost` にアタッチされたリゾルバーがデータを処理している間、`poststatus` はオペレーションの状態で継続的に更新されます。クエリを実行すると、`Post` にはデータの最終ステータスが含まれます。データをスキーマ内でどのように動作させたいかを説明しているだけだということを覚えておいてください。ここではリゾルバーの実装について多くのことを想定しています。リゾルバーは、リクエストを満たすためにデータを処理するための実際のビジネスロジックを実装します。

## オプションとしての考慮事項 - サブスクリプション
<a name="optional-consideration-subscriptions"></a>

 AWS AppSync のサブスクリプションは、ミューテーションへの応答として呼び出されます。サブスクリプションは、`Subscription` 型と `@aws_subscribe()` ディレクティブを使用してスキーマで設定して、どのミューテーションが 1 つまたは複数のサブスクリプションを呼び出すかを示します。サブスクリプションの設定については、「[リアルタイムデータ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)」を参照してください。

## オプションとしての考慮事項 - リレーションとページ分割
<a name="optional-consideration-relations-and-pagination"></a>

DynamoDB テーブルに 100 万個の `Posts` が格納されていて、そのデータの一部を返したいとします。ただし、上記のクエリ例では、すべての投稿を返すだけです。リクエストするたびにこれらすべてを取得したいとは思わないでしょう。代わりに、それらを[ページ分割](https://graphql.org/learn/pagination/)したいと思うかもしれません。スキーマを次のように変更します。
+ `getPosts` フィールドに、`nextToken` (イテレーター) と `limit` (イテレーション制限) の 2 つの入力引数を追加します。
+ `Posts` (`Post` オブジェクトのリストを取得) と `nextToken` (イテレーター) `PostIterator` フィールドを含む新しい タイプを追加します。
+ `getPosts` を変更すると、`Post` オブジェクトのリストではなく、`PostIterator` を返します。

```
schema {
  query: Query
  mutation: Mutation
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}

type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}

type Query {
  getPosts(limit: Int, nextToken: String): PostIterator
}

enum PostStatus {
  success
  pending
  error
}

type PostIterator {
  posts: [Post]
  nextToken: String
}
```

`PostIterator` タイプにより、`Post` オブジェクトのリストと、次ののバッチを取得するための `nextToken` を返すことができます。`PostIterator` 内部には、ページ分割トークン (`nextToken`) とともに返される `Post` アイテム (`[Post]`) のリストがあります。 AWS AppSync では、これはリゾルバーを介して Amazon DynamoDB に接続され、暗号化されたトークンとして自動的に生成されます。マッピングテンプレートにより、`limit` 引数の値は `maxResults` パラメータに変換され、`nextToken` 引数の値は `exclusiveStartKey` パラメータに変換されます。 AWS AppSync コンソールでの例および組み込みテンプレートサンプルについては、「[リゾルバーのリファレンス (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)」を参照してください。

# AWS AppSync でのデータソースのアタッチ
<a name="attaching-a-data-source"></a>

データソースは、GraphQL APIsできる AWS アカウントのリソースです。 AWS AppSync は、Amazon DynamoDB AWS Lambda、リレーショナルデータベース (Amazon Aurora Serverless)、Amazon OpenSearch Service、HTTP エンドポイントなどの多数のデータソースをサポートしています。 AWS AppSync API は、複数のデータソースとやり取りするように設定できるため、データを 1 つの場所に集約できます。 AWS AppSync は、アカウントから既存の AWS リソースを使用するか、スキーマ定義からユーザーに代わって DynamoDB テーブルをプロビジョニングできます。

次のセクションでは、GraphQL API にデータソースをアタッチする方法について説明します。

## データソースのタイプ
<a name="data-source-types"></a>

 AWS AppSync コンソールでスキーマを作成したら、それにデータソースをアタッチできます。API を初めて作成する場合、定義済みスキーマの作成中に Amazon DynamoDB テーブルをプロビジョニングするオプションがあります。ただし、このセクションではそのオプションについては説明しません。この例については、「[Launching a schema](https://docs.aws.amazon.com//appsync/latest/devguide/schema-launch-start.html)」セクションを参照してください。

代わりに、 AWS AppSync がサポートするすべてのデータソースを確認します。アプリケーションに適したソリューションを選ぶ要因は多数あります。以下のセクションでは、各データソースの追加のコンテキストについて説明します。データソースに関する一般的な情報については、「[データソース](https://docs.aws.amazon.com/appsync/latest/devguide/data-source-components.html)」を参照してください。

### Amazon DynamoDB
<a name="data-source-type-ddb"></a>

Amazon DynamoDB は、スケーラブルなアプリケーション向けの主要なストレージソリューションの 1 AWSつです。DynamoDB のコアコンポーネントは **テーブル**で、これは単なるデータのコレクションです。通常テーブルは、`Book` や `Author` などのエンティティに基づいて作成されます。テーブルエントリの情報は、各エントリに固有のフィールドのグループである**アイテム**として保存されます。アイテム全体は、データベース内の 1 つの行またはレコードを表します。たとえば、`Book` エントリのアイテムにはその値とともに `title` と `author` が含まれる場合があります。`title` や `author` などの個々のフィールドは**属性**と呼ばれ、リレーショナルデータベースの列の値に似ています。

ご想像のとおり、テーブルはアプリケーションからのデータの保存に使用されます。 AWS AppSync を使用すると、DynamoDB テーブルを GraphQL API に接続してデータを操作できます。**フロントエンドのウェブとモバイルのブログからこの[ユースケース](https://aws.amazon.com/blogs/mobile/new-real-time-multi-group-app-with-aws-amplify-graphql-build-a-twitter-community-clone/)を見てみましょう。このアプリケーションでは、ユーザーがソーシャルメディアアプリにサインアップできます。ユーザーはグループに参加して投稿をアップロードできます。この投稿は、そのグループに登録している他のユーザーにブロードキャストされます。ユーザーのアプリケーションは、ユーザー、投稿、ユーザーグループの情報を DynamoDB に保存します。GraphQL API ( によって管理 AWS AppSync) は DynamoDB テーブルとインターフェイスします。フロントエンドに反映される変更をユーザーがシステムで行うと、GraphQL API はその変更を取得し、リアルタイムで他のユーザーにブロードキャストします。

### AWS Lambda
<a name="data-source-type-lam"></a>

Lambda は、イベントへの応答としてコードを実行するために必要なリソースを自動的に構築するイベント駆動型サービスです。Lambda は、リソースを実行するためのコード、依存関係、設定を含むグループステートメントである**関数**を使用します。関数は、関数を呼び出すアクティビティのグループである**トリガー**を検出すると自動的に実行されます。トリガーは、API コールを行うアプリケーション、リソースをスピンアップするアカウントの AWS サービスなどです。トリガーされると、関数は、変更するデータを含む JSON ドキュメントである**イベント**を処理します。

Lambda は、コードを実行するためのリソースをプロビジョニングしなくてもコードを実行するのに適しています。**フロントエンドのウェブとモバイルのブログからこの[ユースケース](https://aws.amazon.com/blogs/mobile/building-a-graphql-api-with-java-and-aws-lambda/)を見てみましょう。このユースケースは、DynamoDB セクションで紹介した内容と少し似ています。このアプリケーションでは、GraphQL API により投稿の追加 (ミューテーション) やそのデータの取得 (クエリ) などのオペレーションが定義されます。オペレーション (`getPost ( id: String ! ) : Post`、`getPostsByAuthor ( author: String ! ) : [ Post ]` など) の機能を実装するために、Lambda 関数が使用され、インバウンドリクエストが処理されます。*オプション 2: Lambda リゾルバー AWS AppSync では*、 AWS AppSync サービスを使用してスキーマを維持し、Lambda データソースをオペレーションの 1 つにリンクします。オペレーションが呼び出されると、Lambda は Amazon RDS Proxy とやり取りして、データベース上でビジネスロジックを実行します。

### Amazon RDS
<a name="data-source-type-RDS"></a>

Amazon RDS では、リレーショナルデータベースを迅速に構築して設定できます。Amazon RDS では、クラウド内の隔離されたデータベース環境として機能する汎用**データベースインスタンス**を作成します。このインスタンスでは、実際の RDBMS ソフトウェア (PostgreSQL、MySQL など) である **DB エンジン**を使用します。このサービスは、 AWSインフラストラクチャを使用したスケーラビリティ、パッチ適用や暗号化などのセキュリティサービスを提供し、デプロイの管理コストを削減することで、バックエンド作業の多くをオフロードします。

Lambda セクションの同じ[ユースケース](https://aws.amazon.com/blogs/mobile/building-a-graphql-api-with-java-and-aws-lambda/)を見てみましょう。*オプション 3:Amazon RDS リゾルバー AWS AppSync では*、 の GraphQL API を Amazon RDS に直接リンク AWS AppSync する別のオプションがあります。このオプションでは、[データ API](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html) を使用して、データベースが GraphQL API に関連付けられます。リゾルバーはフィールド (通常はクエリ、ミューテーション、サブスクリプション) にアタッチされ、データベースへのアクセスに必要な SQL ステートメントを実装します。クライアントによってフィールドを呼び出すリクエストが行われると、リゾルバーはステートメントを実行してレスポンスを返します。

### Amazon EventBridge
<a name="data-source-type-eventbridge"></a>

EventBridge では、アタッチするサービスまたはアプリケーション (**イベントソース**) からイベントを受信し、一連のルールに基づいて処理するパイプラインである**イベントバス**を作成します。**イベント**は実行環境における一種の状態の変化であり、**ルール**はイベントのフィルタのセットです。ルールは、**イベントパターン**、すなわちイベントの状態変化のメタデータ (ID、リージョン、アカウント番号、ARN など) に従います。イベントがイベントパターンと一致すると、EventBridge はパイプラインを介して送信先サービス (**ターゲット**) にイベントを送信し、ルールで指定されたアクションをトリガーします。

EventBridge は、状態が変化するオペレーションを他のサービスにルーティングするのに適しています。**フロントエンドのウェブとモバイルのブログからこの[ユースケース](https://aws.amazon.com/blogs/mobile/appsync-eventbridge/)を見てみましょう。この例は、異なるサービスを複数のチームで管理している e コマースソリューションを示しています。これらのサービスの 1 つは、フロントエンドの配送の各ステップ (注文済み、進行中、出荷済み、配送済みなど) で顧客に注文の更新情報を提供します。ただし、このサービスを管理するフロントエンドチームは、別のバックエンドチームによって管理されている注文システムデータに直接アクセスすることはできません。バックエンドチームの注文システムはブラックボックスとも呼ばれており、データの構造化に関する情報を収集するのは困難です。しかし、バックエンドチームは、EventBridge によって管理されるイベントバスを通じて、注文データを発行したシステムをセットアップしました。イベントバスからのデータにアクセスしてフロントエンドにルーティングするために、フロントエンドチームは GraphQL API をポイントする新しいターゲットを作成しました AWS AppSync。また、注文の更新情報に関連するデータのみを送信するルールも作成しました。更新が行われると、イベントバスからのデータが GraphQL API に送信されます。API のスキーマによってデータが処理され、フロントエンドに渡されます。

### none データソース
<a name="data-source-type-none"></a>

データソースを使用する予定がない場合は、データソースを `none` に設定します。`none` データソースは、設定後も明示的にデータソースとして分類されますが、ストレージメディアではありません。通常、リゾルバーはある時点で 1 つ以上のデータソースを呼び出してリクエストを処理します。ただし、データソースを操作する必要がない場合もあります。データソースを `none` に設定すると、リクエストが実行され、データ呼び出しステップはスキップされて、レスポンスが実行されます。

EventBridge セクションの同じ[ユースケース](https://aws.amazon.com/blogs/mobile/appsync-eventbridge/)を見てみましょう。スキーマでは、ミューテーションによりステータスの更新が処理されて、サブスクライバーに送信されます。リゾルバーの仕組み上、通常は少なくとも 1 つのデータソース呼び出しがあります。ただし、このシナリオのデータは既にイベントバスによって自動的に送信されています。つまり、ミューテーションによりデータソース呼び出しが実行される必要はなく、注文状況はローカルで処理するだけで済みます。ミューテーションは `none` に設定され、パススルー値として機能し、データソースは呼び出されません。その後、スキーマにデータが入力され、サブスクライバーに送信されます。

### OpenSearch
<a name="data-source-type-opensearch"></a>

Amazon OpenSearch Service は、全文検索、データ視覚化、ロギングを実装するためのツールスイートです。このサービスを使用すると、アップロードした構造化データをクエリできます。

このサービスでは、OpenSearch のインスタンスを作成します。これらは**ノード**と呼ばれます。ノードには、少なくとも 1 つの**インデックス**を追加します。概念的には、インデックスはリレーショナルデータベースのテーブルに少し似ています (ただし、OpenSearch は ACID に準拠していないため、同じようには使用できません)。OpenSearch サービスにアップロードするデータをインデックスに入力します。データがアップロードされると、インデックス内に存在する 1 つ以上のシャードにインデックスが作成されます。**シャード**は、データの一部を含むインデックスのパーティションのようなもので、他のシャードと別にクエリできます。アップロードされたデータは、**ドキュメント**と呼ばれる JSON ファイルとして構造化されます。その後、ノードに対してドキュメント内のデータをクエリできます。

### HTTP エンドポイント
<a name="data-source-type-http"></a>

HTTP エンドポイントをデータソースとして使用できます。 AWS AppSync は、パラメータやペイロードなどの関連情報を含むリクエストをエンドポイントに送信できます。HTTP レスポンスはリゾルバーに公開され、リゾルバーはオペレーション終了後に最終レスポンスを返します。

## データソースを追加する
<a name="adding-a-data-source"></a>

データソースを作成した場合は、 AWS AppSync サービス、具体的には API にリンクできます。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

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

   1. データソースに名前を付けます。説明を付けることもできますが、これは任意です。

   1. **[データソースタイプ]** を選択します。

   1. DynamoDB の場合は、リージョンを選択してから、リージョンのテーブルを選択する必要があります。新しい汎用テーブルロールを作成するか、テーブルの既存のロールをインポートするかを選択することで、テーブルとのインタラクションルールを設定できます。[バージョニング](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)を有効にすると、複数のクライアントが同時にデータの更新を試行したとき、リクエストごとにデータのバージョンが自動的に作成されます。バージョニングは、競合の検出と解決を目的に、データの複数のバリアントを保持および管理するために使用されます。また、スキーマ自動生成を有効にすると、データソースが取得され、スキーマ内でそのデータソースにアクセスするのに必要な CRUD、`List`、`Query` オペレーションがいくつか生成されます。

      OpenSearch では、リージョンを選択してから、リージョンのドメイン (クラスター) を選択する必要があります。新しい汎用テーブルロールを作成するか、テーブルの既存のロールをインポートするかを選択することで、ドメインとのインタラクションルールを設定できます。

      Lambda の場合は、リージョンを選択してから、そのリージョンの Lambda 関数の ARN を選択する必要があります。新しい汎用テーブルロールを作成するか、テーブルの既存のロールをインポートするかを選択することで、Lambda 関数とのインタラクションルールを設定できます。

      HTTP の場合は、HTTP エンドポイントを入力する必要があります。

      EventBridge の場合は、リージョンを選択してから、地域のイベントバスを選択する必要があります。新しい汎用テーブルロールを作成するか、テーブルの既存のロールをインポートするかを選択することで、イベントバスとのインタラクションルールを設定できます。

      RDS の場合は、リージョンを選択してから、次にシークレットストア (ユーザー名とパスワード)、データベース名、スキーマを選択する必要があります。

      None の場合は、実際のデータソースがないデータソースを追加します。これは、リゾルバーを実際のデータソースではなくローカルで処理するためのものです。
**注記**  
既存のロールをインポートする場合は、信頼ポリシーが必要です。信頼ポリシーの詳細については、「[IAM 信頼ポリシー](#iam-trust-policy.title)」を参照してください。

1. **[作成]** を選択します。
**注記**  
または、DynamoDB データソースを作成する場合は、コンソールの **[スキーマ]** ページに移動し、ページ上部の **[リソースの作成]** を選択してから、定義済みのモデルを入力してテーブルに変換することもできます。このオプションでは、基本型を入力またはインポートし、パーティションキーを含む基本的なテーブルデータを設定して、スキーマの変更を確認します。

------
#### [ CLI ]
+ [https://docs.aws.amazon.com/cli/latest/reference/appsync/create-data-source.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-data-source.html) コマンドを実行してデータソースを作成します。

  この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

  1. API の `api-id` です。

  1. テーブルの `name`。

  1. データソースの `type`。選択したデータソースタイプに応じて、`service-role-arn` と `-config` タグの入力が必要になる場合があります。

  コマンドの例は、次のようになります。

  ```
   aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name data_source_name --type data_source_type --service-role-arn arn:aws:iam::107289374856:role/role_name --[data_source_type]-config {params}
  ```

------
#### [ CDK ]

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/home.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
以下の手順では、特定のリソースを追加するために使用するスニペットの一般的な例のみを示しています。これは本番稼働用コードで機能するソリューションとなることを**意図したものではありません**。また、動作するアプリが既にあることを前提としています。

特定のデータソースを追加するには、コンストラクトをスタックファイルに追加する必要があります。データソースタイプのリストは次のとおりです。
+  [ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
+  [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
+  [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
+  [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
+  [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
+  [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
+  [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 

1. 一般的には、使用しているサービスにインポートディレクティブを追加しなければならない場合があります。たとえば、次の形式に従います。

   ```
   import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
   import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
   ```

   たとえば、 AWS AppSync および DynamoDB サービスをインポートする方法は次のとおりです。

   ```
   import * as appsync from 'aws-cdk-lib/aws-appsync';
   import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
   ```

1. RDS などの一部のサービスでは、データソースを作成する前にスタックファイルに追加の設定が必要です (VPC の作成、ロール、アクセス認証情報など)。詳細については、関連する CDK ページの例を参照してください。

1. ほとんどのデータソース、特に AWS サービスでは、スタックファイルにデータソースの新しいインスタンスを作成します。通常、結果は以下のようになります。

   ```
   const add_data_source_func = new service_scope.resource_name(scope: Construct, id: string, props: data_source_props);
   ```

   その例として、Amazon DynamoDB テーブルの例を次に示します。

   ```
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
     partitionKey: {
       name: 'id',
       type: dynamodb.AttributeType.STRING,
     },
     sortKey: {
       name: 'id',
       type: dynamodb.AttributeType.STRING,
     },
     tableClass: dynamodb.TableClass.STANDARD,
   });
   ```
**注記**  
ほとんどのデータソースには、少なくとも 1 つの必須の props が含まれます (`?` 記号を**使用しない**で表記します)。必要とされる props については、CDK ドキュメントを参照してください。

1. 次に、データソースを GraphQL API にリンクする必要があります。おすすめの方法は、パイプラインリゾルバーの関数を作成するときに追加することです。たとえば、以下のスニペットは DynamoDB テーブルのすべての要素をスキャンする関数です。

   ```
   const add_func = new appsync.AppsyncFunction(this, 'func_ID', {
     name: 'func_name_in_console',
     add_api,
     dataSource: add_api.addDynamoDbDataSource('data_source_name_in_console', add_ddb_table),
     code: appsync.Code.fromInline(`
         export function request(ctx) {
           return { operation: 'Scan' };
         }
   
         export function response(ctx) {
           return ctx.result.items;
         }
     `),
     runtime: appsync.FunctionRuntime.JS_1_0_0,
   });
   ```

   `dataSource` props では、GraphQL API (`add_api`) を呼び出し、その組み込みメソッドの 1 つ (`addDynamoDbDataSource`) を使用して、テーブルと GraphQL API を関連付けることができます。引数は、 AWS AppSync コンソール (`data_source_name_in_console`この例では ) とテーブルメソッド () に存在するこのリンクの名前です`add_ddb_table`。このトピックの詳細は、リゾルバーの作成を開始する次のセクションで明らかになります。

   データソースをリンクする方法は他にもあります。技術的には、テーブル関数の props リストに `api` を追加することもできます。たとえば、以下はステップ 3 のスニペットですが、`api` props には GraphQL API が含まれています。

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     ...
   });
   
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
   
    ...
   
     api: add_api
   });
   ```

   または、`GraphqlApi` コンストラクトを個別に呼び出すこともできます。

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     ...
   });
   
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
     ...
   });
   
   const link_data_source = add_api.addDynamoDbDataSource('data_source_name_in_console', add_ddb_table);
   ```

   アソシエーションは関数の props でのみ作成することをおすすめします。それ以外の場合は、 AWS AppSync コンソールでリゾルバー関数をデータソースに手動でリンクするか (コンソール値 を使用し続ける場合`data_source_name_in_console`)、 のような別の名前で関数に別の関連付けを作成する必要があります`data_source_name_in_console_2`。これは、props による情報処理の方法に制限があるためです。
**注記**  
変更を確認するには、アプリを再デプロイする必要があります。

------

### IAM 信頼ポリシー
<a name="iam-trust-policy"></a>

データソースに既存の IAM ロールを使用している場合は、Amazon DynamoDB テーブルなど、 AWS リソースでオペレーションを実行するための適切なアクセス許可をそのロール`PutItem`に付与する必要があります。また、次のポリシー例に示すように、 AWS AppSync がリソースアクセスに使用するには、そのロールの信頼ポリシーを変更する必要があります。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
        "Effect": "Allow",
        "Principal": {
            "Service": "appsync.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
        }
    ]
}
```

------

また、信頼ポリシーに条件を追加して、必要に応じてデータソースへのアクセスを制限することもできます。現在、`SourceArn`および`SourceAccount`キーはこれらの条件で使用できます。たとえば、次のポリシーでは、データソースへのアクセスを`123456789012` アカウントに制限しています。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        }
      }
    }
  ]
}
```

------

または、データソースへのアクセスを、次のポリシーを使用する`abcdefghijklmnopq`のような特定の API に制限することもできます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:appsync:us-west-2:123456789012:apis/abcdefghijklmnopq"
        }
      }
    }
  ]
}
```

------

以下のポリシー`us-east-1`を使用して、 などの特定のリージョンからのすべての AWS AppSync APIs へのアクセスを制限できます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:appsync:us-east-1:123456789012:apis/*"
        }
      }
    }
  ]
}
```

------

次のセクション (「[リゾルバーの設定](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-config-overview.html)」) では、リゾルバーのビジネスロジックを追加し、スキーマのフィールドにアタッチして、データソースのデータを処理します。

詳細については、**「IAM ユーザーガイド」の「[ロールの修正](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_manage_modify.html)」を参照してください。

AppSync の AWS Lambda リゾルバーのクロスアカウントアクセスの詳細については、「[AWS AppSync のクロスアカウント AWS Lambda リゾルバーの構築](https://aws.amazon.com/blogs/mobile/appsync-lambda-cross-account/)」を参照してください。 AWS AppSync

# AWS AppSync でリゾルバーを設定する
<a name="resolver-config-overview"></a>

前のセクションでは、GraphQL スキーマとデータソースを作成し、それらを AWS AppSync サービス内でリンクする方法を学びました。スキーマでは、クエリとミューテーションに 1 つ以上のフィールド (オペレーション) を設定している場合があります。スキーマには、操作がデータソースに要求するデータの種類が記述されていましたが、それらの操作がデータに対してどのように動作するかは実装されていませんでした。

操作の動作は常にリゾルバーに実装され、リゾルバーは操作を実行するフィールドにリンクされます。リゾルバーの詳細な仕組みについては、[リゾルバー](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)ページを参照してください。

AWS AppSync では、リゾルバーはランタイム、つまりリゾルバーが実行される環境に関連付けられています。ランタイムは、リゾルバーを記述する言語を決定します。現在、APPSYNC\$1JS (JavaScript) と Apache Velocity (VTL) の 2 つのランタイムがサポートされています。

リゾルバーを実装する場合、リゾルバーは次のような一般的な構造になっています。
+ **before Step**: クライアントからリクエストが送信されると、使用中のスキーマフィールド (通常はクエリ、ミューテーション、サブスクリプション) のリゾルバーにリクエストデータが渡されます。リゾルバーは before step ハンドラーを使用してリクエストデータの処理を開始します。これにより、データがリゾルバーを通過する前に一部の前処理操作を実行できます。
+ **関数**: before ステップが実行されると、リクエストは関数リストに渡されます。リストの最初の関数がデータソースに対して実行されます。関数は、独自のリクエストハンドラーとレスポンスハンドラーを含むリゾルバーのコードのサブセットです。リクエストハンドラーはリクエストデータを取得し、データソースに対して操作を実行します。レスポンスハンドラーは、データソースのレスポンスを処理してからリストに戻します。関数が複数ある場合、リクエストデータはリスト内の次に実行される関数に送信されます。リスト内の関数は、開発者が定義した順序で連続して実行されます。すべての関数が実行されると、最終結果は後のステップに渡されます。
+ **after step**: after step は、GraphQL レスポンスに渡す前に、最終関数のレスポンスに対していくつかの最終操作を実行できるハンドラー関数です。

このフローはパイプラインリゾルバーの例です。パイプラインリゾルバーはどちらのランタイムでもサポートされています。ただし、これはパイプラインリゾルバーで何ができるかを簡単に説明したものです。また、ここでは考えられるリゾルバー構成を 1 つだけ説明しています。サポートされているリゾルバー構成の詳細については、APPSYNC\$1JS の「[JavaScript リゾルバーの概要](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)」または VTL の「[リゾルバーマッピングテンプレートの概要](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-overview.html)」を参照してください。

ご覧のとおり、リゾルバーはモジュール式です。リゾルバーのコンポーネントが正しく動作するためには、他のコンポーネントからの実行状態を覗き見できる必要があります。[リゾルバー](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)セクションを見れば、リゾルバーの各コンポーネントには、実行状態に関する重要な情報を一連の引数 (`args`、`context`など) として渡すことができることがわかります。AWS AppSync では、これは `context` が厳密に処理します。これは解決対象のフィールドに関する情報を格納するコンテナです。これには、渡される引数、結果、承認データ、ヘッダーデータなど、あらゆるものが含まれます。コンテキストの詳細については、APPSYNC\$1JS の「[リゾルバーコンテキストオブジェクトリファレンス](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)」または VTL の「リゾルバーマッピングテンプレートコンテキストリファレンス」を参照してください。

リゾルバーの実装に使用できるツールはコンテキストだけではありません。AWS AppSync は値の生成、エラー処理、解析、変換などのための幅広いユーティリティをサポートします。APPSYNC\$1JS の場合は[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)、VTL の場合は[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html)でユーティリティのリストを確認できます。

以下のセクションでは、GraphQL API でリゾルバーを設定する方法を学習します。

**Topics**
+ [基本的なクエリの作成 (JavaScript)](configuring-resolvers-js.md)
+ [基本クエリの作成 (VTL)](configuring-resolvers.md)

# 基本的なクエリの作成 (JavaScript)
<a name="configuring-resolvers-js"></a>

GraphQL リゾルバーは、タイプのスキーマのフィールドをデータソースに接続します。リゾルバーはリクエストを実行するメカニズムです。

 AWS AppSync のリゾルバーは、JavaScript を使用して GraphQL 式をデータソースが使用できる形式に変換します。または、マッピングテンプレートを [Apache Velocity Template Language (VTL)](https://velocity.apache.org/engine/2.0/vtl-reference.html) で記述すると、GraphQL 表現をデータソースで使用できる形式に変換できます。

このセクションでは、JavaScript を使用してリゾルバーを設定する方法を説明します。「[リゾルバーのチュートリアル (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html)」セクションでは、JavaScript を使用してリゾルバーを実装する方法に関する詳細なチュートリアルを提供します。「[リゾルバーのリファレンス (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)」セクションでは、JavaScript リゾルバーと共に使用できるユーティリティオペレーションについて説明します。

前述のチュートリアルを使用する前に、このガイドに従うことをお勧めします。

このセクションでは、リゾルバーを作成してクエリとミューテーションを実行するために設定する方法について説明します。

**注記**  
このガイドでは、スキーマが作成済みで、少なくとも 1 つのクエリまたはミューテーションが含まれていることを前提としています。サブスクリプション (リアルタイムデータ) をお探しの場合は、[このガイド](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)を参照してください。

このセクションでは、リゾルバーを設定する一般的な手順と、以下のスキーマを使用する例を紹介します。

```
// schema.graphql file

input CreatePostInput {
  title: String
  date: AWSDateTime
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
}

type Mutation {
  createPost(input: CreatePostInput!): Post
}

type Query {
  getPost: [Post]
}
```

## 基本的なクエリリゾルバーの作成
<a name="create-basic-query-resolver-js"></a>

このセクションでは、基本的なクエリリゾルバーを作成する方法を説明します。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

1. スキーマとデータソースの詳細を入力します。詳細については、「[スキーマの設計](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)」と「[データソースを追加する](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)」の各セクションを参照してください。

1. **[スキーマ]** エディターの横に **[リゾルバー]** という名前のウィンドウがあります。このボックスには、**[スキーマ]** ウィンドウで定義されているタイプとフィールドのリストが含まれています。フィールドにはリゾルバーをアタッチできます。ほとんどの場合、フィールド処理にリゾルバーをアタッチすることになります。このセクションでは、簡単なクエリの設定について説明します。**[クエリ]** 型で、クエリのフィールドの横にある **[アタッチ]** を選択します。

1. **[リゾルバーをアタッチ]** ページの **[リゾルバータイプ]** で、パイプラインリゾルバーとユニットリゾルバーのどちらかを選択できます。これらのリゾルバータイプの詳細については、「[リゾルバー](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)」を参照してください。このガイドでは `pipeline resolvers` を使用します。
**ヒント**  
パイプラインリゾルバーを作成すると、データソースがパイプライン関数にアタッチされます。関数は、パイプラインリゾルバー自体を作成した後に作成されます。そのため、このページにはこれを設定するオプションはありません。ユニットリゾルバーを使用する場合は、データソースがリゾルバーに直接関連付けられるため、このページで設定します。

   **[リゾルバーランタイム]** では、[`APPSYNC_JS`] を選択して JavaScript ランタイムを有効化します。

1. この API の[キャッシュ](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html)は有効にできます。現時点では、この機能をオフにすることをお勧めします。**[作成]** を選択します。

1. **[リゾルバーを編集]** ページには、リゾルバーハンドラーとレスポンス (before および after ステップ) のロジックを実装できる**リゾルバーコード**というコードエディターがあります。詳細については、「[JavaScript リゾルバーの概要](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)」を参照してください。
**注記**  
この例では、リクエストを空白のままにし、[context](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) からの最後のデータソース結果を返すようにレスポンスを設定します。  

   ```
   import {util} from '@aws-appsync/utils';
   
   export function request(ctx) {
       return {};
   }
   
   export function response(ctx) {
       return ctx.prev.result;
   }
   ```

   このセクションの下には、**[関数]** というテーブルがあります。[関数] では、複数のリゾルバーで再利用できるコードを実装できます。コードを絶えず書き換えたりコピーしたりする代わりに、ソースコードを関数として保存し、必要なときにいつでもリゾルバーに追加できます。

   関数はパイプラインのオペレーションリストの大部分を構成します。リゾルバーで複数の関数を使用する場合、関数の順序を設定すると、関数はその順序で順番に実行されます。これらの関数は、リクエスト関数の実行後、レスポンス関数の開始前に実行されます。

   新しい関数を追加するには、**[関数]** で **[関数を追加]**、**[新しい関数の作成]** の順に選択します。代わりに **[関数の作成]** ボタンが表示されて選択できる場合もあります。

   1. データソースを選択します。これがリゾルバーの処理対象となるデータソースになります。
**注記**  
この例では、`id` で `Post` オブジェクトを取得する `getPost` にリゾルバーをアタッチします。このスキーマ用の DynamoDB テーブルをすでにセットアップ済みであると仮定します。そのパーティションキーは `id` に設定されており、空です。

   1. `Function name` を入力します。

   1. **[関数コード]** で、関数の動作を実装する必要があります。わかりにくいかもしれませんが、各関数には独自のローカルのリクエストハンドラーとレスポンスハンドラーがあります。リクエストが実行され、次にデータソース呼び出しが実行されてリクエストが処理され、データソースのレスポンスがレスポンスハンドラーによって処理されます。結果は [context](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) オブジェクトに保存されます。その後、リスト内の次の関数が実行されるか、それが最後の関数であればステップ後のレスポンスハンドラーに渡されます。
**注記**  
この例では、データソースから `Post` オブジェクトのリストを取得する `getPost` にリゾルバーをアタッチします。リクエスト関数はテーブルにデータをリクエストし、テーブルはレスポンスをコンテキスト (ctx) に渡し、レスポンスは結果をコンテキストに返します。 AWS AppSyncの強度は、他の AWS サービスとの相互接続性にあります。DynamoDB を使用しているため、このような作業を簡略化するための[一連のオペレーション](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html)があります。他のデータソースタイプについても共通する例がいくつかあります。  
コードは以下のようになります。  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Performs a scan on the dynamodb data source
       */
      export function request(ctx) {
        return { operation: 'Scan' };
      }
      
      /**
       * return a list of scanned post items
       */
      export function response(ctx) {
        return ctx.result.items;
      }
      ```
このステップでは、次の 2 つの関数を追加しました。  
`request`: リクエストハンドラーはデータソースに対して取得オペレーションを実行します。引数には、コンテキストオブジェクト (`ctx`)、または特定のオペレーションを実行するすべてのリゾルバーが利用できるデータが含まれます。たとえば、認可データや解決対象のフィールド名などが含まれる場合があります。return ステートメントは [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) オペレーションを実行します (例は[こちら](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html)を参照)。DynamoDB を使用しているため、そのサービスの一部のオペレーションを使用できます。このスキャンでは、テーブル内のすべての項目の基本的なフェッチが実行されます。このオペレーションの結果は、レスポンスハンドラーに渡される前に `result` コンテナーとしてコンテキストオブジェクトに保存されます。`request` はパイプライン内のレスポンス前に実行されます。
`response`: `request` の出力を返すレスポンスハンドラー。引数は、更新されたコンテキストオブジェクトで、return ステートメントは `ctx.prev.result` です。ガイドのこの段階では、この値についてはよくわからないかもしれません。`ctx` は context object オブジェクトを参照します。`prev` はパイプライン内の直前のオペレーション、この例では `request` を参照します。`result` には、リゾルバーがパイプラインを経由して移動する際の結果が含まれます。すべてをまとめると、`ctx.prev.result` は最後に実行されたオペレーションの結果であるリクエストハンドラーを返します。

   1. 完了したら、**[作成]** を選択します。

1. リゾルバー画面に戻り、**[関数]** で **[関数を追加]** ドロップダウンを選択して、関数を関数リストに追加します。

1. **[保存]** を選択してリゾルバーを更新します。

------
#### [ CLI ]

**関数を追加するには**
+ `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)` コマンドを使用してパイプラインリゾルバー用の関数を作成します。

  この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

  1. API の `api-id` です。

  1.  AWS AppSync コンソール`name`の 関数の 。

  1. `data-source-name`、すなわち関数で使用されるデータソースの名前。すでに作成され、 AWS AppSync サービス内の GraphQL API にリンクされている必要があります。

  1. `runtime`、すなわち関数の環境と言語。JavaScript の場合、name は `APPSYNC_JS` で、runtime は `1.0.0` である必要があります。

  1. `code`、すなわち関数のリクエストハンドラーとレスポンスハンドラー。手動でも入力できますが、.txt ファイル (または同様の形式) に追加して引数として渡すほうがはるかに簡単です。
**注記**  
クエリコードは引数として渡されるファイルにあります。  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Performs a scan on the dynamodb data source
      */
     export function request(ctx) {
       return { operation: 'Scan' };
     }
     
     /**
      * return a list of scanned post items
      */
     export function response(ctx) {
       return ctx.result.items;
     }
     ```

  コマンドの例は、次のようになります。

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name get_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file://~/path/to/file/{filename}.{fileType}
  ```

  出力は CLI に返されます。例を示します。

  ```
  {
      "functionConfiguration": {
          "functionId": "ejglgvmcabdn7lx75ref4qeig4",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/ejglgvmcabdn7lx75ref4qeig4",
          "name": "get_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```
**注記**  
`functionId` は、必ずどこかに記録しておいてください。これは、リゾルバーに関数をアタッチする際に使用します。

**リゾルバーを作成するには**
+ `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)` コマンドを実行して `Query` のパイプライン関数を作成します。

  この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

  1. API の `api-id` です。

  1. `type-name`、すなわちスキーマ内の特別なオブジェクトタイプ (クエリ、ミューテーション、サブスクリプション)。

  1. `field-name`、すなわちリゾルバーをアタッチする特別なオブジェクトタイプ内のフィールドオペレーション。

  1. `kind`。ユニットまたはパイプラインリゾルバーを指定します。これを `PIPELINE` に設定すると、パイプライン関数が有効になります。

  1. `pipeline-config`、すなわちリゾルバーにアタッチする関数。関数の `functionId` 値がわかっていることを確認してください。リストの順序は重要です。

  1. `runtime`。以前は `APPSYNC_JS` (JavaScript) でした。`runtimeVersion` は現在、`1.0.0` です。

  1. `code`。before および after ステップハンドラーが含まれています。
**注記**  
クエリコードは引数として渡されるファイルにあります。  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  コマンドの例は、次のようになります。

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Query \
  --field-name getPost \
  --kind PIPELINE \
  --pipeline-config functions=ejglgvmcabdn7lx75ref4qeig4 \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  出力は CLI に返されます。例を示します。

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "getPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/getPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "ejglgvmcabdn7lx75ref4qeig4"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/home.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
以下の手順では、特定のリソースを追加するために使用するスニペットの一般的な例のみを示しています。これは本番稼働用コードで機能するソリューションとなることを**意図したものではありません**。また、動作するアプリが既にあることを前提としています。

基本的なアプリには以下のものが必要です。

1. サービス import ディレクティブ

1. スキーマのコード

1. データソースジェネレーター

1. 関数コード

1. リゾルバーのコード

「[スキーマの設計](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)」と「[データソースを追加する](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)」の各セクションによれば、スタックファイルには以下の形式の import ディレクティブが含まれます。

```
import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
```

**注記**  
前のセクションでは、 AWS AppSync コンストラクトをインポートする方法のみについて説明しました。実際のコードでは、アプリを実行するためだけにより多くのサービスをインポートする必要があります。この例では、非常にシンプルな CDK アプリを作成する場合、少なくとも DynamoDB テーブルであるデータソースとともに AWS AppSync サービスをインポートします。また、アプリをデプロイするには、いくつかの追加コンストラクトをインポートする必要があります。  

```
import * as cdk from 'aws-cdk-lib';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
```
それぞれについて概説すると、次のようになります。  
`import * as cdk from 'aws-cdk-lib';`: これにより、CDK アプリとスタックなどのコンストラクトを定義できます。また、メタデータの操作など、アプリケーションに役立つユーティリティ関数もいくつか含まれています。このインポートディレクティブには精通しているものの、cdk コアライブラリがここで使用される理由が不明の場合は、「[マイグレーション](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html)」ページを参照してください。
`import * as appsync from 'aws-cdk-lib/aws-appsync';`: これにより [AWS AppSync](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html) サービスがインポートされます。
`import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';`: これにより [DynamoDB サービス](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb-readme.html)がインポートされます。
`import { Construct } from 'constructs';`: ルート [コンストラクト](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html)を定義するにはこれが必要です。

インポートの種類は、呼び出すサービスによって異なります。例については、CDK のドキュメントを参照することをお勧めします。ページ上部のスキーマは、CDK アプリでは `.graphql` ファイルとして個別のファイルになります。スタックファイルでは、次の形式でスキーマを新しい GraphQL に関連付けることができます。

```
const add_api = new appsync.GraphqlApi(this, 'graphQL-example', {
  name: 'my-first-api',
  schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphql')),
});
```

**注記**  
スコープ `add_api` では、`new` キーワードの後に `appsync.GraphqlApi(scope: Construct, id: string , props: GraphqlApiProps)` を続けて新しい GraphQL API が追加されています。スコープは `this` で、CFN ID が `graphQL-example` で、props は `my-first-api` (コンソールに表示される API の名前) および `schema.graphql` (スキーマファイルへの絶対パス) です。

データソースを追加するには、まずデータソースをスタックに追加する必要があります。次に、ソース固有のメソッドを使用して GraphQL API に関連付ける必要があります。この関連付けは、リゾルバー関数を作成したときに行われます。その間に、`dynamodb.Table` を使用して DynamoDB テーブルを作成する例を見てみましょう。

```
const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
});
```

**注記**  
この例でこれを使用すると、CFN ID が `posts-table` で、パーティションキーが `id (S)` という新しい DynamoDB テーブルが追加されます。

次に、スタックファイルにリゾルバーを実装する必要があります。DynamoDB テーブル内のすべての項目をスキャンする簡単なクエリの例を以下に示します。

```
const add_func = new appsync.AppsyncFunction(this, 'func-get-posts', {
  name: 'get_posts_func_1',
  add_api,
  dataSource: add_api.addDynamoDbDataSource('table-for-posts', add_ddb_table),
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return { operation: 'Scan' };
      }

      export function response(ctx) {
        return ctx.result.items;
      }
  `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
});

new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
  add_api,
  typeName: 'Query',
  fieldName: 'getPost',
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return {};
      }

      export function response(ctx) {
        return ctx.prev.result;
      }
 `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
  pipelineConfig: [add_func],
});
```

**注記**  
最初に、`add_func` という関数を作成しました。この作成順序は少し直観に反するような印象を持つかもしれませんが、リゾルバー自体を作成する前に、パイプラインリゾルバーで関数を作成する必要があります。関数は次の形式に従います。  

```
AppsyncFunction(scope: Construct, id: string, props: AppsyncFunctionProps)
```
スコープは `this`で、CFN ID が `func-get-posts` で、props には実際に関数の詳細が含まれています。props 内には以下が含まれています。  
 AWS AppSync コンソールに存在する関数`name`の (`get_posts_func_1`)。
以前に作成した GraphQL API (`add_api`)。
データソース。これは、データソースを GraphQL API 値にリンクし、それを関数にアタッチするポイントです。作成したテーブル (`add_ddb_table`) を取得し、`GraphqlApi` メソッド ([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options)) のいずれかを使用して GraphQL API (`add_api`) にアタッチします。ID 値 (`table-for-posts`) は AWS AppSync コンソールに表示されるデータソースの名前です。ソース固有のメソッドの一覧については、次のページを参照してください。  
[ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
 [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
 [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
 [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
 [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
 [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
 [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 
コードには関数のリクエストハンドラーとレスポンスハンドラーが含まれており、シンプルなスキャンを実行し、結果を返します。
ランタイムでは、APPSYNC\$1JS ランタイムバージョン 1.0.0 を使用することを指定しています。現在 APPSYNC\$1JS で使用できるのはこのバージョンだけであることに注意してください。
次に、関数をパイプラインリゾルバーにアタッチする必要があります。リゾルバーは次の形式で作成しています。  

```
Resolver(scope: Construct, id: string, props: ResolverProps)
```
スコープは `this`で、CFN ID が `pipeline-resolver-get-posts` で、props には実際に関数の詳細が含まれています。props 内には以下が含まれています。  
以前に作成した GraphQL API (`add_api`)。
特別なオブジェクトタイプ名。これはクエリオペレーションであり、`Query` 値を追加しただけです。
フィールド名 (`getPost`) は、`Query` タイプのスキーマ内にあるフィールドの名前です。
コードには before ハンドラーと after ハンドラーが含まれています。この例では、関数がオペレーションを実行した後の context 内の結果を返すだけです。
ランタイムでは、APPSYNC\$1JS ランタイムバージョン 1.0.0 を使用することを指定しています。現在 APPSYNC\$1JS で使用できるのはこのバージョンだけであることに注意してください。
パイプライン config には、作成した関数 (`add_func`) への参照が含まれています。

------

この例で何が起こったかを要約すると、リクエストとレスポンスハンドラーを実装した AWS AppSync 関数が表示されました。この関数はデータソースとやりとりする役割を持っています。リクエストハンドラーは に`Scan`オペレーションを送信し AWS AppSync、DynamoDB データソースに対して実行するオペレーションを指示します。レスポンスハンドラーは項目のリスト (`ctx.result.items`) を返します。その後、項目のリストは `Post` GraphQL タイプに自動的にマッピングされました。

## 基本的なミューテーションリゾルバーの作成
<a name="creating-basic-mutation-resolvers-js"></a>

このセクションでは、基本的なミューテーションリゾルバーを作成する方法を説明します。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

1. **[リゾルバー]** セクションと**[ミューテーションタイプ]** で、フィールドの横にある **[アタッチ]** を選択します。
**注記**  
この例では、`createPost` のリゾルバーをアタッチすることで、`Post` オブジェクトをテーブルに追加します。前のセクションと同じ DynamoDB テーブルを使用していると仮定します。そのパーティションキーは `id` に設定されており、空です。

1. **[リゾルバーをアタッチ]** ページの **[リゾルバータイプ]** で、[`pipeline resolvers`] を選択します。リゾルバーの詳細を確認する場合は、[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)を参照してください。**[リゾルバーランタイム]** では、[`APPSYNC_JS`] を選択して JavaScript ランタイムを有効化します。

1. この API の[キャッシュ](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html)は有効にできます。現時点では、この機能をオフにすることをお勧めします。**[作成]** を選択します。

1. **[関数の追加]** を選択して、**[新しい関数を作成]** を選択します。代わりに **[関数の作成]** ボタンが表示されて選択できる場合もあります。

   1.  データソースを選択します。これは、ミューテーション時にデータを操作する際のソースになります。

   1. `Function name` を入力します。

   1. **[関数コード]** で、関数の動作を実装する必要があります。これはミューテーションであるため、リクエストにより、呼び出されたデータソースに対してある程度状態が変化するオペレーションが実行されると理想的です。結果はレスポンス関数によって処理されます。
**注記**  
`createPost` はパラメータがデータとして含まれているテーブルに新しい `Post` ものを追加します (入れます)。次のように追加します。  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Sends a request to `put` an item in the DynamoDB data source
       */
      export function request(ctx) {
        return {
          operation: 'PutItem',
          key: util.dynamodb.toMapValues({id: util.autoId()}),
          attributeValues: util.dynamodb.toMapValues(ctx.args.input),
        };
      }
      
      /**
       * returns the result of the `put` operation
       */
      export function response(ctx) {
        return ctx.result;
      }
      ```
このステップでは、`request` と `response` の 2 つの関数を追加しました。  
`request`: リクエストハンドラーはコンテキストを引数として受け入れます。リクエストハンドラーの return ステートメントは、組み込みの DynamoDB オペレーションである [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem) コマンドを実行します (例については、[こちら](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html)または[こちら](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.WritingData)を参照してください)。`PutItem` このコマンドは、パーティション `key` 値 (`util.autoid()` によって自動的に生成) とコンテキストの引数の入力による `attributes` (リクエストで渡される値) を取得して、`Post` オブジェクトを DynamoDB テーブルに追加します。`key` は、`id` で、`attributes` は `date` および `title` フィールド引数です。どちらも [https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js](https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js)ヘルパーを経由して実行され、DynamoDB テーブルを使用します。
`response`: レスポンスは、更新されたコンテキストを受け入れ、リクエストハンドラーの結果を返します。

   1. 完了したら、**[作成]** を選択します。

1. リゾルバー画面に戻り、**[関数]** で **[関数を追加]** ドロップダウンを選択して、関数を関数リストに追加します。

1. **[保存]** を選択してリゾルバーを更新します。

------
#### [ CLI ]

**関数を追加するには**
+ `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)` コマンドを使用してパイプラインリゾルバー用の関数を作成します。

  この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

  1. API の `api-id` です。

  1.  AWS AppSync コンソール`name`の 関数の 。

  1. `data-source-name`、すなわち関数で使用されるデータソースの名前。すでに作成され、 AWS AppSync サービス内の GraphQL API にリンクされている必要があります。

  1. `runtime`、すなわち関数の環境と言語。JavaScript の場合、name は `APPSYNC_JS` で、runtime は `1.0.0` である必要があります。

  1. `code`、すなわち関数のリクエストハンドラーとレスポンスハンドラー。手動でも入力できますが、.txt ファイル (または同様の形式) に追加して引数として渡すほうがはるかに簡単です。
**注記**  
クエリコードは引数として渡されるファイルにあります。  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({id: util.autoId()}),
         attributeValues: util.dynamodb.toMapValues(ctx.args.input),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  コマンドの例は、次のようになります。

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name add_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  出力は CLI に返されます。例を示します。

  ```
  {
      "functionConfiguration": {
          "functionId": "vulcmbfcxffiram63psb4dduoa",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/vulcmbfcxffiram63psb4dduoa",
          "name": "add_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output foes here"
      }
  }
  ```
**注記**  
`functionId` は、必ずどこかに記録しておいてください。これは、リゾルバーに関数をアタッチする際に使用します。

**リゾルバーを作成するには**
+ `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)` コマンドを実行して `Mutation` のパイプライン関数を作成します。

  この特定のコマンドでは、いくつかのパラメータを入力する必要があります。

  1. API の `api-id` です。

  1. `type-name`、すなわちスキーマ内の特別なオブジェクトタイプ (クエリ、ミューテーション、サブスクリプション)。

  1. `field-name`、すなわちリゾルバーをアタッチする特別なオブジェクトタイプ内のフィールドオペレーション。

  1. `kind`。ユニットまたはパイプラインリゾルバーを指定します。これを `PIPELINE` に設定すると、パイプライン関数が有効になります。

  1. `pipeline-config`、すなわちリゾルバーにアタッチする関数。関数の `functionId` 値がわかっていることを確認してください。リストの順序は重要です。

  1. `runtime`。以前は `APPSYNC_JS` (JavaScript) でした。`runtimeVersion` は現在、`1.0.0` です。

  1. `code`。before および after ステップが含まれています。
**注記**  
クエリコードは引数として渡されるファイルにあります。  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  コマンドの例は、次のようになります。

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Mutation \
  --field-name createPost \
  --kind PIPELINE \
  --pipeline-config functions=vulcmbfcxffiram63psb4dduoa \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  出力は CLI に返されます。例を示します。

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "createPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/createPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "vulcmbfcxffiram63psb4dduoa"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/home.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
以下の手順では、特定のリソースを追加するために使用するスニペットの一般的な例のみを示しています。これは本番稼働用コードで機能するソリューションとなることを**意図したものではありません**。また、動作するアプリが既にあることを前提としています。
+ 同じプロジェクトに属していると仮定して、ミューテーションを行うには、クエリのようにスタックファイルにミューテーションを追加できます。以下は、テーブルに新しい `Post` を追加するミューテーションの修正済み関数とリゾルバーです。

  ```
  const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
    name: 'add_posts_func_1',
    add_api,
    dataSource: add_api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table),
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {
                operation: 'PutItem',
                key: util.dynamodb.toMapValues({id: util.autoId()}),
                attributeValues: util.dynamodb.toMapValues(ctx.args.input),
              };
            }
  
            export function response(ctx) {
              return ctx.result;
            }
        `), 
    runtime: appsync.FunctionRuntime.JS_1_0_0,
  });
  
  new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
    add_api,
    typeName: 'Mutation',
    fieldName: 'createPost',
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {};
            }
  
            export function response(ctx) {
              return ctx.prev.result;
            }
        `),
    runtime: appsync.FunctionRuntime.JS_1_0_0,
    pipelineConfig: [add_func_2],
  });
  ```
**注記**  
このミューテーションとクエリの構造は似ているため、ここではミューテーションを実行するために行った変更について説明します。  
この関数では、テーブルに `Posts` を追加していることを反映して CFN ID を `func-add-post` に、名前を `add_posts_func_1` に変更しました。データソースでは、 `addDynamoDbDataSource` メソッドで必要な`table-for-posts-2`ため、 AWS AppSync コンソールでテーブル (`add_ddb_table`) に新しい関連付けを行いました。この新しい関連付けは、以前に作成したのと同じテーブルをまだ使用していますが、 AWS AppSync コンソールには 2 つの接続があります。1 つはクエリ用で`table-for-posts`、もう 1 つはミューテーション用です`table-for-posts-2`。コードは、`id` 値を自動的に生成し、残りのフィールドのクライアントの入力を受け入れることで、`Post` を追加するように変更されました。  
リゾルバーでは、テーブルに `Posts` を追加していることを反映して ID 値を `pipeline-resolver-create-posts` に変更しました。スキーマのミューテーションを反映するため、タイプ名が `Mutation` に変更され、名前が `createPost` に変更されました。パイプラインの config は、新しいミューテーション関数 `add_func_2` に設定されました。

------

この例で何が起こっているかを要約すると、 は `createPost`フィールドで定義された引数を GraphQL スキーマから DynamoDB オペレーション AWS AppSync に自動的に変換します。`util.autoId()` ヘルパーを使用して自動的に作成される `id` のキーを使用して、DynamoDB にレコードが保存されます。 AWS AppSync コンソールで行われたリクエストまたはそれ以外のリクエストからコンテキスト引数 (`ctx.args.input`) に渡す他のすべてのフィールドは、テーブルの属性として保存されます。キーと属性は両方とも、`util.dynamodb.toMapValues(values)` ヘルパーを使用して互換性のある DynamoDB 形式に自動的にマッピングされます。

AWS AppSync は、リゾルバーを編集するためのテストおよびデバッグワークフローもサポートしています。モック `context` オブジェクトを使用して、呼び出す前にテンプレートでの変換後の値を確認できます。また、クエリを実行する際にデータソースへのリクエスト全体をインタラクティブに表示することもできます。詳細については、「[リゾルバーのテストとデバッグ (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/test-debug-resolvers-js.html)」および「[モニタリングとロギング](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html#aws-appsync-monitoring)」を参照してください。

## 高度なリゾルバー
<a name="advanced-resolvers-js"></a>

「[スキーマの設計](designing-your-schema.md#aws-appsync-designing-your-schema)」のオプションのページネーションセクションに従っている場合でも、ページネーションを利用するにはリゾルバーをリクエストに追加する必要があります。この例では、`getPosts` と呼ばれるクエリページネーションを使用して、リクエストされた内容の一部だけを一度に返します。このフィールドのリゾルバーのコードは以下のようになります。

```
/**
 * Performs a scan on the dynamodb data source
 */
export function request(ctx) {
  const { limit = 20, nextToken } = ctx.args;
  return { operation: 'Scan', limit, nextToken };
}

/**
 * @returns the result of the `put` operation
 */
export function response(ctx) {
  const { items: posts = [], nextToken } = ctx.result;
  return { posts, nextToken };
}
```

リクエストでは、リクエストのコンテキストを渡します。この例では、`limit` は *20* で、最初のクエリでは最大 20 `Posts` を返します。`nextToken` カーソルはデータソースの最初の `Post` エントリに固定されています。これらは args に渡されます。その後、リクエストは最初の `Post` からスキャン制限数までスキャンを実行します。データソースは結果をコンテキストに保存し、その結果はレスポンスに渡されます。レスポンスは取得した `Posts` を返し、`nextToken` が制限数直後の `Post` エントリに設定されます。次のリクエストも送信され、まったく同じ処理が行われますが、最初のクエリの直後のオフセットから開始されます。これらの種類のリクエストは、並列ではなくシーケンシャルに行われることに注意してください。

# AWS AppSync でのリゾルバーのテストとデバッグ (JavaScript)
<a name="test-debug-resolvers-js"></a>

AWS AppSync は、データソースに対して GraphQL フィールドでリゾルバーを実行します。パイプラインリゾルバーを操作する場合、関数はデータソースとやりとりします。「[JavaScript リゾルバーの概要](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)」で説明したように、関数は JavaScript で記述され、ランタイムで実行されるリクエストハンドラーとレスポンスハンドラーを使用してデータソースと通信します`APPSYNC_JS`。これにより、ユーザーはカスタムロジック条件を提供でき、データソースと通信する前後にロジックおよび条件を適用できます。

デベロッパーがこれらのリゾルバーを記述、テスト、デバッグできるように、 AWS AppSync コンソールには、モックデータを含む GraphQL リクエストとレスポンスを個々のフィールドリゾルバーに作成するためのツールも用意されています。さらに、 AWS AppSync コンソールでクエリ、ミューテーション、サブスクリプションを実行し、Amazon CloudWatch からのリクエスト全体の詳細なログストリームを表示できます。ログストリームにはデータソースからの結果も含まれています。

## モックデータを使用したテスト
<a name="testing-with-mock-data-js"></a>

GraphQL リゾルバーが呼び出されるときに、そのリゾルバーには、リクエストに関する情報が含まれている `context` オブジェクトが含まれています。このオブジェクトには、クライアントからの引数、ID 情報、および親 GraphQL フィールドからのデータが含まれています。また、データソースからの結果も含まれていて、それをレスポンスハンドラーで使用できます。この構造およびプログラミング時に使用可能なヘルパーユーティリティの詳細については、「[リゾルバーコンテキストオブジェクトリファレンス](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)」を参照してください。

リゾルバー関数を記述または編集する場合に、*モック*または*コンテキストのテスト*の オブジェクトをコンソールエディタに渡すことができます。これにより、実際にデータソースに対して実行することなく、リクエストとレスポンスハンドラーの両方でどのように評価されるかを確認できます。例えば、テストの `firstname: Shaggy` 引数を渡して、テンプレートのコードで `ctx.args.firstname` を使用している場合にその引数がどのように評価されるかを確認できます。任意のユーティリティヘルパー (`util.autoId()`、`util.time.nowISO8601()` など) での評価をテストすることもできます。

### リゾルバーのテスト
<a name="test-a-resolver-js"></a>

この例では、 AWS AppSync コンソールを使用してリゾルバーをテストします。

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

   1. **サイドバー**で **[関数]** を選択します。

1. 既存の関数を選択します。

1. **[関数の更新]** ページの上部で、**[テストコンテキストを選択]** を選択し、**[新しいコンテキストを作成]** を選択します。

1. サンプルコンテキストオブジェクトを選択するか、下の **[テストコンテキストを設定]** ウィンドウで JSON を手動で入力します。

1. **テキストコンテキスト名**を入力します。

1. **[保存]** ボタンを選択します。

1. この模擬コンテキストオブジェクトを使用してリゾルバーを評価するには、[**Run Test**] を選択します。

例えば、オブジェクトに対して自動 ID 生成を使用して Amazon DynamoDB に保存する `Dog` の GraphQL タイプを保存するアプリケーションがあるとします。また、一部の値を GraphQL ミューテーションの引数から書き込み、レスポンスが特定の 1 人のユーザーにのみ表示されるようにします。次のスニペットがスキーマがどのようになっているかを示します。

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

 AWS AppSync 関数を記述し、リ`addDog`ゾルバーに追加してミューテーションを処理できます。 AWS AppSync 関数をテストするには、次の例のようにコンテキストオブジェクトを入力します。次の例には、クライアントから引数として `name` と `age` があり、`identity` オブジェクトに入力されている `username` があります。

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

次のコードを使用して AWS AppSync 関数をテストできます。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id: util.autoId() }),
    attributeValues: util.dynamodb.toMapValues(ctx.args),
  };
}

export function response(ctx) {
  if (ctx.identity.username === 'Nadia') {
    console.log("This request is allowed")
    return ctx.result;
  }
  util.unauthorized();
}
```

評価後のリクエストとレスポンスハンドラーには、テストコンテキストオブジェクトからのデータと、`util.autoId()` から生成された値があります。また、`username` を `Nadia` 以外の値に変更した場合は、認可チェックが失敗するため、結果は返されません。きめ細かなアクセス制御の詳細については、「[認可のユースケース](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases)」を参照してください。

### AWS AppSync APIs を使用したリクエストハンドラーとレスポンスハンドラーのテスト
<a name="testing-with-appsync-api-js"></a>

`EvaluateCode` API コマンドを使用して、モックデータを使用してコードをリモートでテストできます。コマンドを使い始めるには、ポリシーに `appsync:evaluateMappingCode` アクセス許可を追加していることを確認してください。例えば、次のようになります。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateCode",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

[AWS CLI](https://aws.amazon.com/cli/) または [AWS SDK](https://aws.amazon.com/tools/) を使用してコマンドを活用できます。例えば、前のセクションで `Dog` スキーマとその AWS AppSync 関数のリクエストおよびレスポンスハンドラーを見てみましょう。ローカルステーションの CLI を使用して、コードを `code.js` という名前のファイルに保存し、`context` オブジェクトを `context.json` という名前のファイルに保存します。シェルから次のコマンドを実行します。

```
$ aws appsync evaluate-code \
  --code file://code.js \
  --function response \
  --context file://context.json \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0
```

レスポンスには、ハンドラーから返されたペイロードを含む `evaluationResult` が含まれます。また、評価中にハンドラーによって生成されたログのリストを保持する `logs` オブジェクトも含まれています。これにより、コード実行のデバッグが容易になり、評価に関する情報を確認してトラブルシューティングに役立てることができます。例えば、次のようになります。

```
{
    "evaluationResult": "{\"breed\":\"Miniature Schnauzer\",\"color\":\"black_grey\"}",
    "logs": [
        "INFO - code.js:13:5: \"This request is allowed\""
    ]
}
```

`evaluationResult` は JSON として解析でき、以下を実現します。

```
{
  "breed": "Miniature Schnauzer",
  "color": "black_grey"
}
```

SDK を使用すると、お気に入りのテストスイートのテストを簡単に組み込んで、ハンドラーの動作を検証できます。[Jest テストフレームワーク](https://jestjs.io/)を使用してテストを作成することをお勧めしますが、どのテストスイートでも問題ありません。次のスニペットは、仮説検証の実行を示しています。評価レスポンスは有効な JSON であることを想定しているので、`JSON.parse`を使用して文字列レスポンスから JSON を取得することに注意してください。

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })
const runtime = {name:'APPSYNC_JS',runtimeVersion:'1.0.0')

test('request correctly calls DynamoDB', async () => {
  const code = fs.readFileSync('./code.js', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateCode({ code, context, runtime, function: 'request' }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

 これにより、次のような結果が得られます。

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 totalTime: 1.511 s, estimated 2 s
```

## ライブクエリのデバッグ
<a name="debugging-a-live-query-js"></a>

本番アプリケーションをデバッグするためのend-to-endのテストとログ記録に代わるものはありません。 AWS AppSync では、Amazon CloudWatch を使用してエラーとリクエストの詳細全体をログ記録できます。さらに、 AWS AppSync コンソールを使用して、各リクエストの GraphQL クエリ、ミューテーション、サブスクリプション、ライブストリームログデータをテストし、クエリエディタに戻し、リアルタイムでデバッグできます。サブスクリプションに関して表示されるログは接続時の情報です。

これを実行するには、「[モニタリングとロギング](monitoring.md#aws-appsync-monitoring)」で説明しているように、Amazon CloudWatch Logs を事前に有効にしておく必要があります。次に、 AWS AppSync コンソールで**クエリ**タブを選択し、有効な GraphQL クエリを入力します。右下のセクションで、**[ログ]** ウィンドウをクリックしてドラッグし、ログビューを開きます。ページの上部にある再生矢印アイコンを選択して GraphQL クエリを実行します。しばらくすると、そのオペレーションのリクエストとレスポンスの完全なログが、このセクションにストリーミングされ、コンソールで表示できます。

# AWS AppSync でのパイプラインリゾルバーの設定と使用 (JavaScript)
<a name="pipeline-resolvers-js"></a>

AWS AppSync は GraphQL フィールドでリゾルバーを実行します。場合によっては、アプリケーションは 1 つの GraphQL フィールドを解決するために複数のオペレーションを実行する必要があります。パイプラインリゾルバーを使用すると、開発者は関数と呼ばれるオペレーションを構成して順番に実行できます。パイプラインリゾルバーは、たとえば、フィールドのデータを取得する前に承認チェックを実行する必要があるアプリケーションに便利です。

JavaScript パイプラインリゾルバーのアーキテクチャの詳細については、「[JavaScript リゾルバーの概要](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html#anatomy-of-a-pipeline-resolver-js)」を参照してください。

## ステップ 1: パイプラインリゾルバーを作成する
<a name="create-a-pipeline-resolver-js"></a>

 AWS AppSync コンソールで、**スキーマ**ページに移動します。

以下のスキーマを保存します。

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

パイプラインリゾルバーを**ミューテーション**タイプの **SignUp** フィールドに書き込みます。右側の **[ミューテーション]** タイプに入力し、[`signUp` ミューテーション] フィールドの横の **[アタッチ]** を選択します。リゾルバーを `pipeline resolver` および `APPSYNC_JS` ランタイムに設定し、リゾルバーを作成します。

パイプラインリゾルバーは、最初に E メールアドレスの入力を検証してからシステムにユーザーを保存することで、ユーザーをサインアップします。E メールの検証を **validateEmail** 関数内にカプセル化し、ユーザーの保存を **saveUser** 関数内にカプセル化します。**validateEmail** 関数が最初に実行され、E メールが有効であれば、**saveUser** 関数が実行されます。

実行フローは以下のようになります。

1. Mutation.SignUp リゾルバーリクエストハンドラー

1. validateEmail 関数

1. saveUser 関数

1. Mutation.SignUp リゾルバーレスポンスハンドラー

API の他のリゾルバーで **validateEmail** 関数を再利用することが多いため、GraphQL フィールド間でアクセス先の `ctx.args` が変わるのを避けるとします。この場合、代わりに `ctx.stash` を使用して、`signUp(input: Signup)` 入力フィールド引数からの email 属性を保存できます。

リクエスト関数とレスポンス関数を置き換えてリゾルバーコードを更新してください。

```
export function request(ctx) {
    ctx.stash.email = ctx.args.input.email
    return {};
}

export function response(ctx) {
    return ctx.prev.result;
}
```

**[作成]** または **[保存]** を選択してリゾルバーを更新します。

## ステップ 2: 関数を作成する
<a name="create-a-function-js"></a>

パイプラインリゾルバーページの **[関数]** セクションで、**[関数の作成]** をクリックして、**[新しい関数の作成]** をクリックします。リゾルバーページを経由せずに関数を作成することもできます。これを行うには、 AWS AppSync コンソールで**関数**ページに移動します。**[関数の作成]** ボタンを選択します。E メールが有効であり特定のドメインからのものかどうかをチェックする関数を作成しましょう。E メールが無効な場合、この関数はエラーを発生させます。それ以外の場合、渡された入力をすべて転送します。

**NONE** タイプのデータソースを作成したことを確認してください。**[データソース名]** リストでこのデータソースを選択します。**関数名**として、「`validateEmail`」と入力します。**関数コード**領域で、次のスニペットですべてを上書きします。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { email } = ctx.stash;
  const valid = util.matches(
    '^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com',
    email
  );
  if (!valid) {
    util.error(`"${email}" is not a valid email.`);
  }

  return { payload: { email } };
}

export function response(ctx) {
  return ctx.result;
}
```

選択内容を確認し、**[作成]** を選択します。これで、**validateEmail** 関数が作成されました。次のコードでこれらの手順を繰り返し、**saveUser** 関数を作成します (わかりやすくするため、**NONE** データソースを使用し、関数が実行された後にユーザーがシステムに保存されたものとしています。):

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  return ctx.prev.result;
}

export function response(ctx) {
  ctx.result.id = util.autoId();
  return ctx.result;
}
```

これで、**saveUser** 関数が作成されました。

## ステップ 3: パイプラインリゾルバーに関数を追加する
<a name="adding-a-function-to-a-pipeline-resolver-js"></a>

先ほど作成したパイプラインリゾルバーには関数が自動的に追加されています。そうでない場合や、**[関数]** ページから関数を作成した場合は、`signUp` リゾルバーページの **[関数を追加]** をクリックして、関数をアタッチできます。**validateEmail** と **saveUser** の両方の関数をリゾルバーに追加します。**validateEmail** 関数は **saveUser** 関数の前に配置する必要があります。関数を追加するときには、**上に移動**および**下に移動**オプションを使用して関数の実行順序を並べ替えることができます。変更を確認し、**[保存]** を選択します。

## ステップ 4: クエリを実行する
<a name="running-a-query-js"></a>

 AWS AppSync コンソールで、**クエリ**ページに移動します。Explorer で、ミューテーションを使用していることを確認します。そうでない場合は、ドロップダウンリストから [`Mutation`] を選択し、[`+`] を選択します。以下のクエリを入力します。

```
mutation {
  signUp(input: {email: "nadia@myvaliddomain.com", username: "nadia"}) {
    id
    username
  }
}
```

以下のように返されます。

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "username": "nadia"
    }
  }
}
```

これで、パイプラインリゾルバーを使用して、ユーザーをサインアップし、入力 E メールを検証できました。

# 基本クエリの作成 (VTL)
<a name="configuring-resolvers"></a>

**注記**  
現在、主に APPSYNC\$1JS ランタイムとそのドキュメントをサポートしています。[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html)にある APPSYNC\$1JS ランタイムとそのガイドの使用をご検討ください。

GraphQL リゾルバーは、タイプのスキーマのフィールドをデータソースに接続します。リゾルバーは、リクエストが受理されるメカニズムです。 AWS AppSync は、コードを記述することなく、スキーマからリゾルバーを自動的に作成して接続したり、スキーマを作成して既存のテーブルからリゾルバーに接続したりできます。

 AWS AppSync のリゾルバーは、JavaScript を使用して GraphQL 式をデータソースが使用できる形式に変換します。または、マッピングテンプレートを [Apache Velocity Template Language (VTL)](https://velocity.apache.org/engine/2.0/vtl-reference.html) で記述すると、GraphQL 表現をデータソースで使用できる形式に変換できます。

このセクションでは、VTL を使用してリゾルバーを設定する方法について説明します。リゾルバーを記述するための入門チュートリアル形式のプログラミングガイドは、[リゾルバーマッピングテンプレートプログラミングガイド](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide)に記載されています。プログラミング時に使用できるヘルパーユーティリティは、[リゾルバーマッピングテンプレートコンテキストリファレンス](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference)にあります。 AWS AppSync には、ゼロから編集またはオーサリングするときに使用できるテストおよびデバッグフローも組み込まれています。詳細については、「[リゾルバーのテストとデバッグ](test-debug-resolvers.md#aws-appsync-test-debug-resolvers)」を参照してください。

前述のチュートリアルを使用する前に、このガイドに従うことをお勧めします。

このセクションでは、リゾルバーを作成する方法、ミューテーション用のリゾルバーを追加する方法、詳細設定を使用する方法について説明します。

## 最初のリゾルバーを作成する
<a name="create-your-first-resolver"></a>

前のセクションの例に従うと、最初のステップとして、ご使用の `Query` タイプに合ったリゾルバーを作成します。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

1. ページの右側には、**[リゾルバー]** というウィンドウがあります。このボックスには、ページの左側の **[スキーマ]** ウィンドウで定義されているタイプとフィールドのリストが含まれています。リゾルバーはフィールドにアタッチできます。たとえば、**[クエリ]** タイプで、`getTodos` フィールドの横にある **[アタッチ]** を選択します。

1. **[リゾルバーの作成]** ページで、「[データソースを追加する](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)」ガイドで作成したデータソースを選択します。**[マッピングテンプレートの設定]** ウィンドウでは、右側のドロップダウンリストを使用して汎用のリクエストおよびレスポンスのマッピングテンプレートを両方とも選択することも、独自のテンプレートを作成することもできます。
**注記**  
リクエストマッピングテンプレートとレスポンスマッピングテンプレートの組み合わせをユニットリゾルバーと呼びます。ユニットリゾルバーは通常、機械的なオペレーションを実行するためのものであるため、データソース数が少ない単一のオペレーションのみに使用することをおすすめします。より複雑なオペレーションには、複数のデータソースで複数のオペレーションを連続して実行できるパイプラインリゾルバーの使用をお勧めします。  
リクエストマッピングテンプレートとレスポンスマッピングテンプレートの違いの詳細については、「[ユニットリゾルバー](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-mapping-template-reference-overview.html#unit-resolvers)」を参照してください。  
パイプラインリゾルバーの使用に関する詳細については、「[パイプラインリゾルバー](pipeline-resolvers.md#aws-appsync-pipeline-resolvers)」を参照してください。

1. 一般的なユースケースでは、 AWS AppSync コンソールには、データソースから項目を取得するために使用できる組み込みテンプレート (すべての項目クエリ、個々のルックアップなど) があります。たとえば、「[スキーマの設計](designing-your-schema.md#aws-appsync-designing-your-schema)」で使用したスキーマのシンプルバージョンでは、`getTodos` にページ分割がなく、項目を一覧表示するためのリクエストマッピングテンプレートは次のようになっていました。

   ```
   {
       "version" : "2017-02-28",
       "operation" : "Scan"
   }
   ```

1. リクエストに関連付けるレスポンスマッピングテンプレートが常に必要になります。コンソールには、リストの値をパススルーする次のようなデフォルトのテンプレートがあります。

   ```
   $util.toJson($ctx.result.items)
   ```

   この例では、項目のリストに対する `context` オブジェクト (`$ctx` としてエイリアスが作成された) の形式は `$context.result.items` です。GraphQL オペレーションが 1 つの項目を返す場合、 になります`$context.result`。 AWS AppSync は、レスポンスを適切にフォーマットするために、前述の関数など、一般的なオペレーション用のヘルパー`$util.toJson`関数を提供します。関数の完全なリストについては、「[リゾルバーのマッピングテンプレートのユーティリティリファレンス](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference)」を参照してください。

1. **[リゾルバーを保存]** を選択します。

------
#### [ API ]

1. [https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html) API を呼び出して、リゾルバーオブジェクトを作成します。

1. [https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html) API を呼び出して、リゾルバーのフィールドを変更できます。

------
#### [ CLI ]

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html) コマンドを実行してリゾルバーを作成します。

   このコマンドには次の 6 つのパラメータを入力する必要があります。

   1. API の `api-id`。

   1. スキーマ内で変更するタイプの `type-name`。このコンソールの例では、`Query` です。

   1. タイプ内で変更するフィールドの `field-name`。このコンソールの例では、`getTodos` です。

   1. 「[データソースを追加する](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)」ガイドで作成したデータソースの `data-source-name`。

   1. `request-mapping-template`。リクエストの本文です。このコンソールの例では、次のようになります。

      ```
      {
          "version" : "2017-02-28",
          "operation" : "Scan"
      }
      ```

   1. `response-mapping-template`。リクエストの本文です。このコンソールの例では、次のようになります。

      ```
      $util.toJson($ctx.result.items)
      ```

   コマンドの例は、次のようになります。

   ```
   aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Query --field-name getTodos --data-source-name TodoTable --request-mapping-template "{ "version" : "2017-02-28", "operation" : "Scan", }" --response-mapping-template ""$"util.toJson("$"ctx.result.items)"
   ```

   出力は CLI に返されます。例を示します。

   ```
   {
       "resolver": {
           "kind": "UNIT",
           "dataSourceName": "TodoTable",
           "requestMappingTemplate": "{ version : 2017-02-28, operation : Scan, }",
           "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Query/resolvers/getTodos",
           "typeName": "Query",
           "fieldName": "getTodos",
           "responseMappingTemplate": "$util.toJson($ctx.result.items)"
       }
   }
   ```

1. リゾルバーのフィールドおよび/またはマッピングテンプレートを変更するには、[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html) コマンドを実行します。

   `api-id` パラメータを除いて、`create-resolver` コマンドで使用されたパラメータは、`update-resolver` コマンドの新しい値で上書きされます。

------

## ミューテーション用のリゾルバーの追加
<a name="adding-a-resolver-for-mutations"></a>

次のステップは、ご使用の `Mutation` タイプに合ったリゾルバーを作成することです。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

1. **[ミューテーション]** タイプで、`addTodo` フィールドの横にある **[アタッチ]** を選択します。

1. **[リゾルバーの作成]** ページで、「[データソースを追加する](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)」ガイドで作成したデータソースを選択します。

1. このミューテーションでは DynamoDB に新しい項目を追加するため、**[マッピングテンプレートの設定]** ウィンドウでリクエストテンプレートを変更する必要があります。次のリクエストマッピングテンプレートを使用します。

   ```
   {
       "version" : "2017-02-28",
       "operation" : "PutItem",
       "key" : {
           "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
       },
       "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
   }
   ```

1. AWS AppSync は、 `addTodo`フィールドで定義された引数を GraphQL スキーマから DynamoDB オペレーションに自動的に変換します。上記の例では、ミューテーションの引数で `$ctx.args.id` として渡された `id` のキーを使用して、レコードが DynamoDB に保存されます。渡した他のすべてのフィールドは、`$util.dynamodb.toMapValuesJson($ctx.args)` を使用して自動的に DynamoDB 属性にマッピングされます。

   このリゾルバーでは、次のレスポンスマッピングテンプレートを使用します。

   ```
   $util.toJson($ctx.result)
   ```

   AWS AppSync は、リゾルバーを編集するためのテストワークフローとデバッグワークフローもサポートしています。モック `context` オブジェクトを使用して、呼び出す前にテンプレートでの変換後の値を確認できます。また、クエリを実行する際にデータソースへのリクエストの実行全体をインタラクティブに表示することもできます。詳細については、「[リゾルバーのテストとデバッグ](test-debug-resolvers.md#aws-appsync-test-debug-resolvers)」および「[モニタリングとロギング](monitoring.md#aws-appsync-monitoring)」を参照してください。

1. **[リゾルバーを保存]** を選択します。

------
#### [ API ]

API では、[[最初のリゾルバーを作成する]](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) セクションのコマンドと、このセクションのパラメータの詳細を利用することで、これを行うこともできます。

------
#### [ CLI ]

CLI では、[[最初のリゾルバーを作成する]](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) セクションのコマンドと、このセクションのパラメータの詳細を利用することで、これを行うこともできます。

------

この時点で、高度なリゾルバーを使用していない場合は、「[API の使用](using-your-api.md#aws-appsync-using-your-api)」で説明されているよう GraphQL API の使用を開始できます。

## 高度なリゾルバー
<a name="advanced-resolvers"></a>

「[スキーマの設計](designing-your-schema.md#aws-appsync-designing-your-schema)」でのサンプルスキーマの構築の「高度な機能」セクションに従ってページ分割スキャンを行う場合は、代わりに `getTodos` フィールドに次のリクエストテンプレートを使用します。

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "limit": $util.defaultIfNull(${ctx.args.limit}, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.nextToken, null))
}
```

このページ分割のユースケースでは、レスポンスマッピングに *cursor* (クライアントが次の開始ページを知るため) と結果セットの両方が含まれている必要があるため、レスポンスマッピングは単なるパススルーではありません。マッピングテンプレートは次のようになります。

```
{
    "todos": $util.toJson($context.result.items),
    "nextToken": $util.toJson($context.result.nextToken)
}
```

前述のレスポンスマッピングテンプレート内のフィールドは、`TodoConnection` 型で定義されているフィールドと一致している必要があります。

`Comments` テーブルがあり、`Todo` 型の comments フィールドを解決するリレーション (`[Comment]` の型を返す) の場合は、2 番目のテーブルに対してクエリを実行するマッピングテンプレートを使用できます。これを行うには、「[データソースをアタッチする](attaching-a-data-source.md#aws-appsync-getting-started-build-a-schema-from-scratch)」で説明しているように `Comments` テーブルのデータソースを作成しておく必要があります。

**注記**  
ここで 2 番目のテーブルに対するクエリオペレーションを使用しているのは、例を示すことのみを目的としています。代わりに、DynamoDB に対して別のオペレーションを使用できます。さらに、リレーションは GraphQL スキーマによって制御されるため、 AWS Lambda や Amazon OpenSearch Service などの別のデータソースからデータを取得できます。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

1. **[Todo]** タイプで、`comments` フィールドの横にある **[アタッチ]** を選択します。

1. **[リゾルバーの作成]** ページで、**Comments** テーブルのデータソースを選択します。クイックスタートガイドの **Comments** テーブルのデフォルト名は `AppSyncCommentTable` ですが、指定した名前によって異なる場合があります。

1. リクエストマッピングテンプレートに次のスニペットを追加します。

   ```
   {
       "version": "2017-02-28",
       "operation": "Query",
       "index": "todoid-index",
       "query": {
           "expression": "todoid = :todoid",
           "expressionValues": {
               ":todoid": {
                   "S": $util.toJson($context.source.id)
               }
           }
       }
   }
   ```

1. `context.source` は、解決する現在のフィールドの親オブジェクトを参照します。この例では、`source.id` は個別の `Todo` オブジェクトを参照します。これはクエリ式に使用されます。

   次のようにパススルーのレスポンスマッピングテンプレートを使用できます。

   ```
   $util.toJson($ctx.result.items)
   ```

1. **[リゾルバーを保存]** を選択します。

1. 最後に、コンソールの **[スキーマ]** ページで、リゾルバーを `addComment` フィールドにアタッチして `Comments` テーブルのデータソースを指定します。この例のリクエストマッピングテンプレートは、引数としてコメントされる特定の `todoid` を含む単純な `PutItem` ですが、次のように `$utils.autoId()` ユーティリティを使用してコメントに対して一意なソートキーを作成します。

   ```
   {
       "version": "2017-02-28",
       "operation": "PutItem",
       "key": {
           "todoid": { "S": $util.toJson($context.arguments.todoid) },
           "commentid": { "S": "$util.autoId()" }
       },
       "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
   }
   ```

   次のようにパススルーレスポンステンプレートを使用します。

   ```
   $util.toJson($ctx.result)
   ```

------
#### [ API ]

API では、[[最初のリゾルバーを作成する]](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) セクションのコマンドと、このセクションのパラメータの詳細を利用することで、これを行うこともできます。

------
#### [ CLI ]

CLI では、[[最初のリゾルバーを作成する]](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) セクションのコマンドと、このセクションのパラメータの詳細を利用することで、これを行うこともできます。

------

# ダイレクト Lambda リゾルバー (VTL) を使用した VTL マッピングテンプレートの無効化
<a name="direct-lambda-reference"></a>

**注記**  
現在、主に APPSYNC\$1JS ランタイムとそのドキュメントをサポートしています。[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html) で APPSYNC\$1JS ランタイムとそのガイドの使用をご検討ください。

直接 Lambda リゾルバーを使用すると、 AWS Lambda データソースを使用するときに VTL マッピングテンプレートの使用を回避できます。 AWS AppSync は、Lambda 関数へのデフォルトのペイロードと、GraphQL タイプへの Lambda 関数のレスポンスからのデフォルトの変換を提供できます。リクエストテンプレート、レスポンステンプレート、またはどちらも指定できず、 AWS AppSync はそれに応じて処理します。

 AWS AppSync が提供するデフォルトのリクエストペイロードとレスポンス変換の詳細については、[「Direct Lambda リゾルバーリファレンス](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers)」を参照してください。 AWS Lambda データソースの設定と IAM 信頼ポリシーの設定の詳細については、[「データソースのアタッチ](attaching-a-data-source.md)」を参照してください。

## ダイレクト Lambda リゾルバーを設定する
<a name="direct-lambda-reference-resolvers"></a>

以下のセクションでは、Lambda データソースをアタッチし、Lambda リゾルバーをフィールドに追加する方法を示します。

### Lambda データソースを追加する
<a name="direct-lambda-datasource"></a>

ダイレクト Lambda リゾルバーをアクティブ化する前に、Lambda データソースを追加する必要があります。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

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

   1. **データソース名**を使用する場合、**myFunction** のようなデータソースの名前を入力します。

   1. [**データソースタイプ**] で [**AWS Lambda 関数**] を選択します。

   1. [**リージョン**] で、該当するリージョンを選択します。

   1. **関数 ARN**を使用する場合は、ドロップダウンリストから Lambda 関数を選択します。関数名を検索するか、使用する関数の ARN を手動で入力します。

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

      次に、リソースで操作を実行するために必要なアクセス許可を持つ IAM ポリシーの例を示します。

------
#### [ JSON ]

****  

      ```
      { 
           "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:*" 
                   ] 
               } 
           ] 
       }
      ```

------

1. **[サーバーの作成]** ボタンを選択します。

------
#### [ CLI ]

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html) コマンドを実行してデータソースオブジェクトを作成します。

   このコマンドには次の 4 つのパラメータを入力する必要があります。

   1. API の `api-id` です。

   1. データソースの `name`。コンソールの例では、これは**データソース名**です。

   1. データソースの `type`。コンソールの例では、これは**AWS Lambda 関数**です。

   1. コンソールの例では**関数 ARN** の `lambda-config`。
**注記**  
`Region` など、設定する必要のあるパラメータは他にもありますが、通常はデフォルトで CLI 設定値になります。

   コマンドの例は、次のようになります。

   ```
   aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name myFunction --type AWS_LAMBDA --lambda-config lambdaFunctionArn=arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example
   ```

   出力は CLI に返されます。例を示します。

   ```
   {
       "dataSource": {
           "dataSourceArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/datasources/myFunction",
           "type": "AWS_LAMBDA",
           "name": "myFunction",
           "lambdaConfig": {
               "lambdaFunctionArn": "arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example"
           }
       }
   }
   ```

1. データソースの属性を変更するには、[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html) コマンドを実行します。

   `api-id` パラメータを除いて、`create-data-source` コマンドで使用されているパラメータは、`update-data-source` コマンドの新しい値で上書きされます。

------

### ダイレクト Lambda リゾルバをアクティブ化する
<a name="direct-lambda-enable-templates"></a>

Lambda データソースを作成し、 AWS AppSync が関数を呼び出せるように適切な IAM ロールを設定したら、リゾルバーまたはパイプライン関数にリンクできます。

------
#### [ Console ]

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

1. **[リゾルバー]** セクションで、フィールドまたはオペレーションを選択し、**[アタッチ]** ボタンを選択します。

1. **新しいリゾルバーを作成する**ページで、ドロップダウンリストから Lambda 関数を選択します。

1. ダイレクト Lambda リゾルバーを利用するには、リクエストとレスポンスのマッピングテンプレートが**マッピングテンプレートを設定する**セクションで無効になっていることを確認します。

1. **[リゾルバーの保存]** ボタンを選択します。

------
#### [ CLI ]
+ [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html) コマンドを実行してリゾルバーを作成します。

  このコマンドには次の 6 つのパラメータを入力する必要があります。

  1. API の `api-id`。

  1. スキーマでのタイプの `type-name`。

  1. スキーマでのフィールドの `field-name`。

  1. `data-source-name`、または Lambda 関数の名前。

  1. リクエストの本文である `request-mapping-template`。コンソールの例では、これは無効になっています。

     ```
     " "
     ```

  1. レスポンスの本文である `response-mapping-template`。コンソールの例では、これも無効になっています。

     ```
     " "
     ```

  コマンドの例は、次のようになります。

  ```
  aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Subscription --field-name onCreateTodo --data-source-name LambdaTest --request-mapping-template " " --response-mapping-template " "
  ```

  出力は CLI に返されます。例を示します。

  ```
  {
      "resolver": {
          "resolverArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/types/Subscription/resolvers/onCreateTodo",
          "typeName": "Subscription",
          "kind": "UNIT",
          "fieldName": "onCreateTodo",
          "dataSourceName": "LambdaTest"
      }
  }
  ```

------

マッピングテンプレートを無効にすると、 AWS AppSyncで発生する追加の動作がいくつかあります。
+ マッピングテンプレートを無効にすると、[Direct Lambda リゾルバーリファレンス](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers)で指定されたデフォルトのデータ変換を受け入れる AWS AppSync ことを に知らせます。
+ リクエストマッピングテンプレートを無効にすると、Lambda データソースは、[Context](resolver-context-reference.md)オブジェクト全体で構成されるペイロードを受け取ります。
+ レスポンスマッピングテンプレートを無効にすると、リクエストマッピングテンプレートのバージョン、またはリクエストマッピングテンプレートも無効になっているかどうかに応じて、Lambda 呼び出しの結果が変換されます。

# AWS AppSync (VTL) でのリゾルバーのテストとデバッグ
<a name="test-debug-resolvers"></a>

**注記**  
現在、主に APPSYNC\$1JS ランタイムとそのドキュメントをサポートしています。[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html) で APPSYNC\$1JS ランタイムとそのガイドの使用をご検討ください。

AWS AppSync は、データソースに対して GraphQL フィールドでリゾルバーを実行します。「[リゾルバーのマッピングテンプレートの概要](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)」で説明しているように、リゾルバーはテンプレート作成言語を使用してデータソースと通信します。これにより、ユーザーは動作をカスタマイズでき、データソースと通信する前後にロジックおよび条件を適用できます。リゾルバーを記述するための入門者向けのチュートリアル形式プログラミングガイドについては、「[リゾルバーのマッピングテンプレートのプログラミングガイド](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide)」を参照してください。

デベロッパーがこれらのリゾルバーを記述、テスト、デバッグできるように、 AWS AppSync コンソールには、モックデータを含む GraphQL リクエストとレスポンスを個々のフィールドリゾルバーに作成するためのツールも用意されています。さらに、 AWS AppSync コンソールでクエリ、ミューテーション、サブスクリプションを実行し、リクエスト全体の Amazon CloudWatch からの詳細なログストリームを表示できます。ログストリームにはデータソースからの結果も含まれています。

## モックデータを使用したテスト
<a name="testing-with-mock-data"></a>

GraphQL リゾルバーが呼び出されるときに、そのリゾルバーには、リクエストに関する情報を含む `context` オブジェクトが含まれています。このオブジェクトには、クライアントからの引数、ID 情報、および親 GraphQL フィールドからのデータが含まれています。また、データソースからの結果も含まれていて、それをレスポンステンプレートで使用できます。この構造体およびプログラミング時に使用可能なヘルパーユーティリティの詳細については、「[リゾルバーのマッピングテンプレートのコンテキストリファレンス](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference)」を参照してください。

リゾルバーを記述または編集する場合に、*モック*または*テストコンテキスト*オブジェクトをコンソールエディタに渡すことができます。これにより、実際にデータソースに対して実行することなく、リクエストとレスポンスの両方のテンプレートでどのように評価されるかを確認できます。例えば、テストの `firstname: Shaggy` 引数を渡して、テンプレートのコードで `$ctx.args.firstname` を使用している場合にその引数がどのように評価されるかを確認できます。任意のユーティリティヘルパー (`$util.autoId()`、`util.time.nowISO8601()` など) での評価をテストすることもできます。

### リゾルバーのテスト
<a name="test-a-resolver"></a>

この例では、 AWS AppSync コンソールを使用してリゾルバーをテストします。

1. にサインイン AWS マネジメントコンソール し、[AppSync コンソール](https://console.aws.amazon.com/appsync/)を開きます。

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

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

1. まだ行っていない場合は、タイプの下のフィールドの横にある **[アタッチ]** を選択してリゾルバーを追加します。

   完全なリゾルバーをビルドする方法の詳細については、「[リゾルバーを設定する](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html)」を参照してください。

   それ以外の場合は、すでにフィールドにあるリゾルバーを選択してください。

1. **[リゾルバーを編集]** ページの上部で、**[テストコンテキストを選択]** を選択し、**[新しいコンテキストを作成]** を選択します。

1. サンプルコンテキストオブジェクトを選択するか、下の**実行コンテキスト**ウィンドウに JSON を手動で入力します。

1. **テキストコンテキスト名**を入力します。

1. **[保存]** ボタンを選択します。

1. **[リゾルバーを編集]** ページの上部にある **[テストを実行]** を選択します。

より現実的な例として、オブジェクトに対して自動 ID 生成を使用して Amazon DynamoDB に保存する `Dog` の GraphQL タイプを保存するアプリケーションがあるとします。また、一部の値を GraphQL ミューテーションの引数から書き込み、レスポンスが特定の 1 人のユーザーにのみ表示されるようにします。スキーマは次のようになります。

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

`addDog` ミューテーションに対してリゾルバーを追加するときに、次のようなコンテキストオブジェクトを入力できます。次の例には、クライアントから引数として `name` と `age` があり、`identity` オブジェクトに入力されている `username` があります。

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

これを、以下のリクエストとレスポンスのマッピングテンプレートを使用してテストします。

 **リクエストテンプレート** 

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "id" : { "S" : "$util.autoId()" }
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

 **レスポンステンプレート** 

```
#if ($context.identity.username == "Nadia")
  $util.toJson($ctx.result)
#else
  $util.unauthorized()
#end
```

評価後のテンプレートには、テストコンテキストオブジェクトからのデータと、`$util.autoId()` から生成された値があります。また、`username` を `Nadia` 以外の値に変更した場合は、認可チェックが失敗するため、結果は返されません。きめ細かなアクセス制御の詳細については、「[認可のユースケース](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases)」を参照してください。

### AWS AppSync の APIs を使用したマッピングテンプレートのテスト
<a name="testing-with-appsync-api"></a>

`EvaluateMappingTemplate` API コマンドを使用して、モックデータを使用してマッピングテンプレートをリモートでテストできます。コマンドを使い始めるには、ポリシーに `appsync:evaluateMappingTemplate` アクセス許可を追加していることを確認してください。例えば、次のようになります。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateMappingTemplate",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

[AWS CLI](https://aws.amazon.com/cli/) または [AWS SDK](https://aws.amazon.com/tools/) を使用してコマンドを活用できます。例えば、前のセクションから、`Dog` スキーマとそのリクエスト/レスポンスマッピングテンプレートを見てみましょう。ローカルステーションの CLI を使用して、リクエストテンプレートを `request.vtl` という名前のファイルに保存し、`context` オブジェクトを `context.json` という名前のファイルに保存します。シェルから次のコマンドを実行します。

```
aws appsync evaluate-mapping-template --template file://request.vtl --context file://context.json
```

このコマンドは、次のレスポンスを返します。

```
{
  "evaluationResult": "{\n    \"version\" : \"2017-02-28\",\n    \"operation\" : \"PutItem\",\n    \"key\" : {\n        \"id\" : { \"S\" : \"afcb4c85-49f8-40de-8f2b-248949176456\" }\n    },\n    \"attributeValues\" : {\"firstname\":{\"S\":\"Shaggy\"},\"age\":{\"N\":4}}\n}\n"
}
```

`evaluationResult` には、提供されたテンプレートを提供された `context` とともにテストした結果が含まれています。 AWS SDKs を使用してテンプレートをテストすることもできます。 AWS SDK for JavaScript V2 を使用した例を次に示します。

```
const AWS = require('aws-sdk')
const client = new AWS.AppSync({ region: 'us-east-2' })

const template = fs.readFileSync('./request.vtl', 'utf8')
const context = fs.readFileSync('./context.json', 'utf8')

client
  .evaluateMappingTemplate({ template, context })
  .promise()
  .then((data) => console.log(data))
```

SDK を使用すると、お気に入りのテストスイートのテストを簡単に組み込んで、テンプレートの動作を検証できます。[Jest テストフレームワーク](https://jestjs.io/)を使用してテストを作成することをお勧めしますが、どのテストスイートでも問題ありません。次のスニペットは、仮説検証の実行を示しています。評価レスポンスは有効な JSON であることを想定しているので、`JSON.parse`を使用して文字列レスポンスから JSON を取得することに注意してください。

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })

test('request correctly calls DynamoDB', async () => {
  const template = fs.readFileSync('./request.vtl', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateMappingTemplate({ template, context }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

 これにより、次のような結果が得られます。

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.511 s, estimated 2 s
```

## ライブクエリのデバッグ
<a name="debugging-a-live-query"></a>

本番アプリケーションをデバッグするためのend-to-endのテストとログ記録に代わるものはありません。 AWS AppSync では、Amazon CloudWatch を使用してエラーとリクエストの詳細全体をログ記録できます。さらに、 AWS AppSync コンソールを使用して、各リクエストの GraphQL クエリ、ミューテーション、サブスクリプション、ライブストリームログデータをテストし、クエリエディタに戻し、リアルタイムでデバッグできます。サブスクリプションに関して表示されるログは接続時の情報です。

これを実行するには、「[モニタリングとロギング](monitoring.md#aws-appsync-monitoring)」で説明しているように、Amazon CloudWatch Logs を事前に有効にしておく必要があります。次に、 AWS AppSync コンソールで**クエリ**タブを選択し、有効な GraphQL クエリを入力します。右下のセクションで、**[ログ]** ウィンドウをクリックしてドラッグし、ログビューを開きます。ページの上部にある再生矢印アイコンを選択して GraphQL クエリを実行します。しばらくすると、そのオペレーションのリクエストとレスポンスの完全なログが、このセクションにストリーミングされ、コンソールで表示できます。

# AWS AppSync (VTL) でのパイプラインリゾルバーの設定と使用
<a name="pipeline-resolvers"></a>

**注記**  
現在、主に APPSYNC\$1JS ランタイムとそのドキュメントをサポートしています。[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html) で APPSYNC\$1JS ランタイムとそのガイドの使用をご検討ください。

AWS AppSync は GraphQL フィールドでリゾルバーを実行します。場合によっては、アプリケーションは 1 つの GraphQL フィールドを解決するために複数のオペレーションを実行する必要があります。パイプラインリゾルバーを使用すると、開発者は関数と呼ばれるオペレーションを構成して順番に実行できます。パイプラインリゾルバーは、たとえば、フィールドのデータを取得する前に承認チェックを実行する必要があるアプリケーションに便利です。

パイプラインリゾルバーは、**Before** マッピングテンプレート、**After** マッピングテンプレート、関数のリストで構成されています。各関数には、データソースに対して実行される**リクエスト**および**レスポンス**マッピングテンプレートがあります。パイプラインリゾルバーは実行をリスト内の関数に委任するため、いずれのデータソースにもリンクされていません。ユニットリゾルバーと関数は、データソースに対してオペレーションを実行するプリミティブです。詳細については、「[リゾルバーのマッピングテンプレートの概要](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)」を参照してください。

## ステップ 1: パイプラインリゾルバーを作成する
<a name="create-a-pipeline-resolver"></a>

 AWS AppSync コンソールで、**スキーマ**ページに移動します。

以下のスキーマを保存します。

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

パイプラインリゾルバーを**ミューテーション**タイプの **SignUp** フィールドに書き込みます。右側の **[ミューテーション]** タイプに入力し、[`signUp` ミューテーション] フィールドの横の **[アタッチ]** を選択します。[リゾルバーの作成] ページで、**[アクション]**、**[ランタイム更新]** の順にクリックします。[`Pipeline Resolver`]、[`VTL`] の順に選択してから、**[更新]** を選択します。このページには、**Before マッピングテンプレート**テキスト領域、**関数**セクション、**After マッピングテンプレート**テキスト領域の 3 つのセクションが表示されています。

パイプラインリゾルバーは、最初に E メールアドレスの入力を検証してからシステムにユーザーを保存することで、ユーザーをサインアップします。E メールの検証を **validateEmail** 関数内にカプセル化し、ユーザーの保存を **saveUser** 関数内にカプセル化します。**validateEmail** 関数が最初に実行され、E メールが有効であれば、**saveUser** 関数が実行されます。

実行フローは以下のようになります。

1. Mutation.signUp リゾルバーのリクエストマッピングテンプレート

1. validateEmail 関数

1. saveUser 関数

1. Mutation.signUp リゾルバーのレスポンスマッピングテンプレート

API の他のリゾルバーで **validateEmail** 関数を再利用することが多いため、GraphQL フィールド間でアクセス先の `$ctx.args` が変わるのを避けるとします。この場合、代わりに `$ctx.stash` を使用して、`signUp(input: Signup)` 入力フィールド引数からの email 属性を保存できます。

**BEFORE** マッピングテンプレート:

```
## store email input field into a generic email key
$util.qr($ctx.stash.put("email", $ctx.args.input.email))
{}
```

コンソールから、デフォルトのパススルー **AFTER** マッピングテンプレートを使用できます。

```
$util.toJson($ctx.result)
```

**[作成]** または **[保存]** を選択してリゾルバーを更新します。

## ステップ 2: 関数を作成する
<a name="create-a-function"></a>

パイプラインリゾルバーページの **[関数]** セクションで、**[関数の作成]** をクリックして、**[新しい関数の作成]** をクリックします。リゾルバーページを経由せずに関数を作成することもできます。これを行うには、 AWS AppSync コンソールで**関数**ページに移動します。**[関数の作成]** ボタンを選択します。E メールが有効であり特定のドメインからのものかどうかをチェックする関数を作成しましょう。E メールが無効な場合、この関数はエラーを発生させます。それ以外の場合、渡された入力をすべて転送します。

新しい関数ページで、**[アクション]** を選択して、**[ランタイムを更新]** を選択します。[`VTL`] を選択してから、**[更新]** を選択します。**NONE** 型のデータソースが作成されたことを確認してください。**[データソース名]** リストでこのデータソースを選択します。**[関数名]** に `validateEmail` と入力します。**関数コード** 領域で、次のスニペットですべてを上書きします。

```
#set($valid = $util.matches("^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com", $ctx.stash.email))
#if (!$valid)
    $util.error("$ctx.stash.email is not a valid email.")
#end
{
    "payload": { "email": $util.toJson(${ctx.stash.email}) }
}
```

レスポンスマッピングテンプレートにこれを貼り付けます。

```
$util.toJson($ctx.result)
```

変更内容を確認し、**[作成]** を選択します。これで、**validateEmail** 関数が作成されました。次のリクエストマッピングテンプレートとレスポンスマッピングテンプレートでこれらの手順を繰り返し、**saveUser** 関数を作成します (わかりやすくするため、**NONE** データソースを使用し、関数が実行された後にユーザーがシステムに保存されたものとしています。): 

リクエストマッピングテンプレート:

```
## $ctx.prev.result contains the signup input values. We could have also
## used $ctx.args.input.
{
    "payload": $util.toJson($ctx.prev.result)
}
```

レスポンスマッピングテンプレート

```
## an id is required so let's add a unique random identifier to the output
$util.qr($ctx.result.put("id", $util.autoId()))
$util.toJson($ctx.result)
```

これで、**saveUser** 関数が作成されました。

## ステップ 3: パイプラインリゾルバーに関数を追加する
<a name="adding-a-function-to-a-pipeline-resolver"></a>

先ほど作成したパイプラインリゾルバーには関数が自動的に追加されています。そうでない場合、または **[関数]** ページで関数を作成した場合は、リゾルバーページの **[関数を追加]** をクリックして、それらの関数をアタッチできます。**validateEmail** と **saveUser** の両方の関数をリゾルバーに追加します。**validateEmail** 関数は **saveUser** 関数の前に配置する必要があります。関数を追加するときには、**上に移動**および**下に移動**オプションを使用して関数の実行順序を並べ替えることができます。変更を確認し、**[保存]** を選択します。

## ステップ 4: クエリを実行する
<a name="executing-a-query"></a>

 AWS AppSync コンソールで、**クエリ**ページに移動します。Explorer で、ミューテーションを使用していることを確認します。そうでない場合は、ドロップダウンリストから [`Mutation`] を選択し、[`+`] を選択します。以下のクエリを入力します。

```
mutation {
  signUp(input: {
    email: "nadia@myvaliddomain.com"
    username: "nadia"
  }) {
    id
    email
  }
}
```

以下のように返されます。

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "email": "nadia@myvaliddomain.com"
    }
  }
}
```

これで、パイプラインリゾルバーを使用して、ユーザーをサインアップし、入力 E メールを検証できました。パイプラインリゾルバーに焦点を当てたより完全なチュートリアルについては、「[チュートリアル: パイプラインリゾルバー](tutorial-pipeline-resolvers.md#aws-appsync-tutorial-pipeline-resolvers)」を参照してください。

# AWS CDK での AWS AppSync API の使用
<a name="using-your-api"></a>

**ヒント**  
CDK を使用する前に、CDK の[公式ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html)と CDK AWS AppSyncリファレンスを確認することをお勧めします。 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
また、[AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) と [NPM](https://docs.npmjs.com/) のインストールがシステム上で動作していることを確認することをお勧めします。

このセクションでは、DynamoDB テーブルに項目を追加したり、テーブルから項目を取得したりできる簡単な CDK アプリケーションを作成します。これは、[[スキーマの設計]](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)、[[データソースのアタッチ]](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)、[[リゾルバーの設定 (JavaScript)]](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html) セクションのコードの一部を使用したクイックスタートの例です。

## CDK プロジェクトのセットアップ
<a name="Setting-up-a-cdk-project"></a>

**警告**  
環境によっては、これらの手順が完全に正確ではない場合があります。システムに必要なユーティリティがインストールされていること、 AWS サービスとインターフェイスする方法、および適切な設定が整っていることを前提としています。

最初のステップは AWS CDK のインストールです。CLI で、次のコマンドを入力できます。

```
npm install -g aws-cdk
```

次に、プロジェクトディレクトリを作成して、そこに移動する必要があります。ディレクトリを作成して、そこに移動するコマンドのセット例は次のとおりです。

```
mkdir example-cdk-app
cd example-cdk-app
```

次に、アプリを作成する必要があります。私たちのサービスは主に TypeScript を使用しています。プロジェクトディレクトリで次のコマンドを入力します。

```
cdk init app --language typescript
```

これを行うと、CDK アプリとその初期化ファイルがインストールされます。

![\[Terminal output showing Git repository initialization and npm install completion.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-init-app-example.png)


プロジェクト構造は次のようになります。

![\[Project directory structure showing folders and files for an example CDK app.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-init-directories.png)


いくつかの重要なディレクトリがあるのがわかります。
+ `bin`: 最初の bin ファイルによってアプリが作成されます。このガイドではこれについては触れません。
+ `lib`: lib ディレクトリにはスタックファイルが含まれます。スタックファイルは個々の実行単位と考えることができます。コンストラクトはスタックファイル内にあります。基本的に、これらはアプリケーションのデプロイ CloudFormation 時に でスピンアップされるサービスのリソースです。ほとんどのコーディングはここで行われます。
+ `node_modules`: このディレクトリは NPM によって作成され、`npm` コマンドを使用してインストールしたすべてのパッケージ依存関係が含まれます。

最初のスタックファイルには次のような内容が含まれる場合があります。

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';

export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    // example resource
    // const queue = new sqs.Queue(this, 'ExampleCdkAppQueue', {
    //   visibilityTimeout: cdk.Duration.seconds(300)
    // });
  }
}
```

これはアプリでスタックを作成するためのボイラープレートコードです。この例では、コードのほとんどはこのクラスのスコープ内にあります。

スタックファイルがアプリ内にあることを確認し、アプリのディレクトリからターミナルで以下のコマンドを実行します。

```
cdk ls
```

スタックが一覧表示されます。表示されない場合は、手順をもう一度実行するか、公式ドキュメントでヘルプを確認する必要があります。

デプロイする前にコードの変更をビルドする場合は、ターミナルでいつでも以下のコマンドを実行できます。

```
npm run build
```

また、デプロイ前に変更を確認します。

```
cdk diff
```

スタックファイルにコードを追加する前に、ブートストラップを実行します。ブートストラップにより、アプリがデプロイされる前に CDK にリソースをプロビジョニングできます。このプロセスの詳細については、[こちら](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html)を参照してください。ブートストラップを作成するには、以下のコマンドを実行します。

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

**ヒント**  
このステップでは、アカウントに複数の IAM アクセス許可が必要です。これらのアクセス許可がないと、ブートストラップは拒否されます。拒否された場合、ブートストラップが生成する S3 バケットなど、ブートストラップが原因で発生した不完全なリソースを削除しなければならない場合があります。

ブートストラップは複数のリソースを起動します。最終メッセージは次のようになります。

![\[Terminal output showing successful bootstrapping of an AWS environment.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-init-bootstrap-final.png)


これは各リージョンのアカウントごとに 1 回行われるため、頻繁に行う必要はありません。ブートストラップの主なリソースは、 CloudFormation スタックと Amazon S3 バケットです。

Amazon S3 バケットは、ファイルとデプロイの実行に必要なアクセス許可を付与する IAM ロールを保存するために使用されます。必要なリソースは、ブートストラップ CloudFormation スタックと呼ばれる スタックで定義され、通常は と呼ばれます`CDKToolkit`。他の CloudFormation スタックと同様に、デプロイされると CloudFormation コンソールに表示されます。

![\[CDKToolkit stack with CREATE_COMPLETE status in CloudFormation console.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-init-bootstrap-cfn-console.png)


バケットについても同じことが言えます。

![\[S3 bucket details showing name, region, access settings, and creation date.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-init-bootstrap-bucket-console.png)


スタックファイルで必要なサービスをインポートするには、以下のコマンドを使用できます。

```
npm install aws-cdk-lib # V2 command
```

**ヒント**  
V2 に問題がある場合は、V1 コマンドを使用して個々のライブラリをインストールできます。  

```
npm install @aws-cdk/aws-appsync @aws-cdk/aws-dynamodb
```
V1 は廃止されたため、これはお勧めしません。

## CDK プロジェクトを作成する - スキーマ
<a name="implementing-a-cdk-project-schema"></a>

これで、コードの実装を開始できます。まず、スキーマを作成する必要があります。アプリ内で `.graphql` ファイルを作成するだけです。

```
mkdir schema
touch schema.graphql
```

この例では、`schema.graphql` を含む `schema` という最上位ディレクトリを含めました。

![\[File structure showing a schema folder containing schema.graphql file.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-schema-directory.png)


スキーマの中に、簡単な例を含めてみましょう。

```
input CreatePostInput {
    title: String
    content: String
}

type Post {
    id: ID!
    title: String
    content: String
}

type Mutation {
    createPost(input: CreatePostInput!): Post
}

type Query {
    getPost: [Post]
}
```

スタックファイルに戻って、次の import ディレクティブが定義されていることを確認する必要があります。

```
import * as cdk from 'aws-cdk-lib';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
```

クラス内に、GraphQL API を作成して `schema.graphql` ファイルに接続するコードを追加します。

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    // makes a GraphQL API
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });
  }
}
```

また、GraphQL URL、API キー、リージョンを出力するコードもいくつか追加します。

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

この時点で、アプリを再度デプロイします。

```
cdk deploy
```

こちらがその結果です。

![\[Deployment output showing ExampleCdkAppStack details, including GraphQL API URL and stack region.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-schema.png)


この例は成功したようですが、 AWS AppSync コンソールを確認して確認しましょう。

![\[GraphQL interface showing successful API request with response data displayed.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-schema-result-1.png)


API が作成されたようです。次に、API に添付されているスキーマを確認します。

![\[GraphQL schema defining CreatePostInput, Post type, Mutation, and Query operations.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-schema-result-2.png)


これはスキーマコードと一致しているようなので、成功です。メタデータの観点からこれを確認するもう 1 つの方法は、 CloudFormation スタックを確認することです。

![\[CloudFormation stack showing ExampleCdkAppStack update complete and CDKToolkit creation complete.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-schema-result-3.png)


CDK アプリケーションをデプロイすると、ブートストラップなどのリソース CloudFormation がスピンアップされます。アプリ内の各スタックは、 CloudFormation スタックと 1:1 でマッピングされます。スタックコードに戻ると、スタック名はクラス名 `ExampleCdkAppStack` から取得されています。作成したリソースを確認でき、GraphQL API コンストラクトの命名規則とも一致しています。

![\[Expanded view of post-apis resource showing Schema, DefaultApiKey, and CDKMetadata.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-schema-result-4.png)


## CDK プロジェクトの実装 - データソース
<a name="implementing-a-cdk-project-data-source"></a>

次に、データソースを追加する必要があります。この例では DynamoDB テーブルを使用します。stack クラス内に、新しいテーブルを作成するコードをいくつか追加します。

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    //creates a DDB table
    const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

この時点で、もう一度デプロイしてみましょう。

```
cdk deploy
```

DynamoDB コンソールで新しいテーブルを確認する必要があります。

![\[DynamoDB console showing ExampleCdkAppStack-poststable as Active with Provisioned capacity.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-1.png)


スタック名は正しく、テーブル名はコードと一致しています。 CloudFormation スタックを再度チェックすると、新しいテーブルが表示されます。

![\[Expanded view of a logical ID in CloudFormation showing post-apis, posts-table, and CDKMetadata.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-2.png)


## CDK プロジェクトを作成する - リゾルバー
<a name="implementing-a-cdk-project-resolver"></a>

この例では、2 つのリゾルバーを使用します。1 つはテーブルのクエリ用、もう 1 つはテーブルへの追加用です。パイプラインリゾルバーを使用しているため、それぞれ 1 つの関数を持つ 2 つのパイプラインリゾルバーを宣言する必要があります。このクエリでは、次のコードを追加します。

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    //creates a DDB table
    const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
    });

    // Creates a function for query
    const add_func = new appsync.AppsyncFunction(this, 'func-get-post', {
      name: 'get_posts_func_1',
      api,
      dataSource: api.addDynamoDbDataSource('table-for-posts', add_ddb_table),
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return { operation: 'Scan' };
          }

          export function response(ctx) {
          return ctx.result.items;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });

    // Creates a function for mutation
    const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
      name: 'add_posts_func_1',
      api,
      dataSource: api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table),
      code: appsync.Code.fromInline(`
          export function request(ctx) {
            return {
            operation: 'PutItem',
            key: util.dynamodb.toMapValues({id: util.autoId()}),
            attributeValues: util.dynamodb.toMapValues(ctx.args.input),
            };
          }

          export function response(ctx) {
            return ctx.result;
          }
      `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });

    // Adds a pipeline resolver with the get function
    new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
      api,
      typeName: 'Query',
      fieldName: 'getPost',
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return {};
          }

          export function response(ctx) {
          return ctx.prev.result;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
      pipelineConfig: [add_func],
    });

    // Adds a pipeline resolver with the create function
    new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
      api,
      typeName: 'Mutation',
      fieldName: 'createPost',
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return {};
          }

          export function response(ctx) {
          return ctx.prev.result;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
      pipelineConfig: [add_func_2],
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

このスニペットでは、`func-add-post` という関数がアタッチされた `pipeline-resolver-create-posts` というパイプラインリゾルバーを追加しました。これがテーブルに `Posts` を追加するコードです。もう一方のパイプラインリゾルバーは `pipeline-resolver-get-posts` と呼ばれ、テーブルに追加された `Posts` を取得する `func-get-post` と呼ばれる関数を持ちます。

これをデプロイして AWS AppSync サービスに追加します。

```
cdk deploy
```

 AWS AppSync コンソールをチェックして、それらが GraphQL API にアタッチされているかどうかを確認します。

![\[GraphQL API schema showing mutation and query fields with Pipeline resolvers.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-1.png)


正しく接続されているようです。コードでは、これらのリゾルバーは両方とも、作成した GraphQL API にアタッチされていました (リゾルバーと関数の両方に存在する `api` props 値で示されます)。GraphQL APIでは、リゾルバーをアタッチしたフィールドも props で指定されていました (各リゾルバーで `typename` および `fieldname` props によって定義されます)。

リゾルバーのコンテンツが正しいかどうか、`pipeline-resolver-get-posts` を手始めに見てみましょう。

![\[Code snippet showing request and response functions in a resolver, with an arrow pointing to them.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-2.png)


before ハンドラーと after ハンドラーは `code` props の値と一致しています。また、`add_posts_func_1` という関数がリゾルバーにアタッチした関数の名前と一致していることもわかります。

この関数のコードコンテンツを見てみましょう。

![\[Function code showing request and response methods for a PutItem operation.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-3.png)


これは `add_posts_func_1` 関数の `code` props と一致します。クエリが正常にアップロードされたので、クエリを確認してみましょう。

![\[Resolver code with request and response functions, and a get_posts_func_1 function listed below.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-4.png)


これらもコードと一致しています。`get_posts_func_1` を見てみましょう。

![\[Code snippet showing two exported functions: request returning 'Scan' operation and response returning items.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-5.png)


すべてが正常に見えます。メタデータの観点からこれを確認するには、スタックをもう一度 CloudFormation にチェックインします。

![\[List of logical IDs for AWS resources including API, table, functions, and pipelines.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-6.png)


次に、いくつかのリクエストを実行して、このコードをテストする必要があります。

## CDK プロジェクトの実装 - リクエスト
<a name="implementing-a-cdk-project-requests"></a>

 AWS AppSync コンソールでアプリケーションをテストするために、1 つのクエリと 1 つのミューテーションを作成しました。

![\[GraphQL code snippet showing a query to get post details and a mutation to create a post.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-request-1.png)


`MyMutation` には、引数 `1970-01-01T12:30:00.000Z` と `first post` を含む `createPost` オペレーションが含まれています。渡した `date` および `title` とともに、自動生成された `id` 値が返されます。ミューテーションを実行すると、以下の結果が得られます。

```
{
  "data": {
    "createPost": {
      "date": "1970-01-01T12:30:00.000Z",
      "id": "4dc1c2dd-0aa3-4055-9eca-7c140062ada2",
      "title": "first post"
    }
  }
}
```

DynamoDB テーブルをすばやく確認すると、スキャンしたときにテーブルにエントリが表示されます。

![\[DynamoDB table entry showing id, date, and title fields for a single item.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/cdk-code-request-2.png)


 AWS AppSync コンソールに戻り、クエリを実行してこの を取得すると`Post`、次の結果が得られます。

```
{
  "data": {
    "getPost": [
      {
        "id": "9f62c4dd-49d5-48d5-b835-143284c72fe0",
        "date": "1970-01-01T12:30:00.000Z",
        "title": "first post"
      }
    ]
  }
}
```