

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

# 基本的なクエリの作成 (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 メールを検証できました。