

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

# での AWS Lambda リゾルバーの使用 AWS AppSync
<a name="tutorial-lambda-resolvers"></a>

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

 AWS Lambda with AWS AppSync を使用して、GraphQL フィールドを解決できます。例えば、GraphQL クエリが Amazon Relational Database Service (Amazon RDS) インスタンスを呼び出し、GraphQL のミューテーションを Amazon Kinesis ストリームに書き込むことができます。このセクションでは、GraphQL フィールド処理の呼び出しに応じてビジネスロジックを実行する Lambda 関数を記述する方法について説明します。

## Lambda 関数を作成する
<a name="create-a-lam-function"></a>

以下の例は、`Node.js` に記述された、ブログ投稿アプリケーションの一部としてブログ投稿に関するさまざまなオペレーションを実行する Lambda 関数を示しています。

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    var posts = {
         "1": {"id": "1", "title": "First book", "author": "Author1", "url": "https://amazon.com/", "content": "SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1", "ups": "100", "downs": "10"},
         "2": {"id": "2", "title": "Second book", "author": "Author2", "url": "https://amazon.com", "content": "SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT", "ups": "100", "downs": "10"},
         "3": {"id": "3", "title": "Third book", "author": "Author3", "url": null, "content": null, "ups": null, "downs": null },
         "4": {"id": "4", "title": "Fourth book", "author": "Author4", "url": "https://www.amazon.com/", "content": "SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4", "ups": "1000", "downs": "0"},
         "5": {"id": "5", "title": "Fifth book", "author": "Author5", "url": "https://www.amazon.com/", "content": "SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT", "ups": "50", "downs": "0"} };

    var relatedPosts = {
        "1": [posts['4']],
        "2": [posts['3'], posts['5']],
        "3": [posts['2'], posts['1']],
        "4": [posts['2'], posts['1']],
        "5": []
    };

    console.log("Got an Invoke Request.");
    switch(event.field) {
        case "getPost":
            var id = event.arguments.id;
            callback(null, posts[id]);
            break;
        case "allPosts":
            var values = [];
            for(var d in posts){
                values.push(posts[d]);
            }
            callback(null, values);
            break;
        case "addPost":
            // return the arguments back
            callback(null, event.arguments);
            break;
        case "addPostErrorWithData":
            var id = event.arguments.id;
            var result = posts[id];
            // attached additional error information to the post
            result.errorMessage = 'Error with the mutation, data has changed';
            result.errorType = 'MUTATION_ERROR';
            callback(null, result);
            break;
        case "relatedPosts":
            var id = event.source.id;
            callback(null, relatedPosts[id]);
            break;
        default:
            callback("Unknown field, unable to resolve" + event.field, null);
            break;
    }
};
```

この Lambda 関数は、ID による投稿の取得、投稿の追加、投稿のリストの取得、および指定した投稿に関連する投稿の取得を行います。

 **注意 :** `event.field` の `switch` ステートメントにより、Lambda 関数は現在解決しているフィールドを確認することができます。

 AWS マネジメントコンソールまたは AWS CloudFormation スタックを使用して、この Lambda 関数を作成します。CloudFormation スタックから関数を作成するには、次の AWS Command Line Interface (AWS CLI) コマンドを使用できます。

```
aws cloudformation create-stack --stack-name AppSyncLambdaExample \
--template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/lambda/LambdaCFTemplate.yaml \
--capabilities CAPABILITY_NAMED_IAM
```

ここから AWS 、アカウントの米国西部 (オレゴン) AWS リージョンで CloudFormation スタックを起動することもできます。

[https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/lambda/LambdaCFTemplate.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/lambda/LambdaCFTemplate.yaml)

## Lambda のデータソースを設定する
<a name="configure-data-source-for-lamlong"></a>

Lambda 関数を作成した後、 AWS AppSync コンソールで GraphQL API に移動し、**[データソース]** タブを選択します。

**[データソースの作成]** を選択し、**[データソース名]**としてわかりやすい名前 (**Lambda** など) を入力してから、**[データソースタイプ]** に対して **[AWS Lambda 関数]**を選択します。**[リージョン]** で、関数と同じリージョンを選択します。(提供されている CloudFormation スタックから関数を作成した場合、その関数はおそらく **US-WEST-2** にあります)。**[関数 ARN]** で、Lambda 関数の Amazon リソースネーム (ARN)を選択します。

Lambda 関数を選択したら、新しい AWS Identity and Access Management (IAM) ロール ( AWS AppSync が適切なアクセス許可を割り当てるロール) を作成するか、次のインラインポリシーを持つ既存のロールを選択できます。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": "arn:aws:lambda:us-east-1:111122223333:function:LAMBDA_FUNCTION"
        }
    ]
}
```

------

また、次のように IAM ロールの AWS AppSync との信頼関係を設定する必要があります。

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

****  

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

------

## GraphQL スキーマを作成する
<a name="creating-a-graphql-schema"></a>

データソースが Lambda 関数に接続されたので、GraphQL スキーマを作成します。

 AWS AppSync コンソールのスキーマエディタから、スキーマが次のスキーマと一致していることを確認します。

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

type Query {
    getPost(id:ID!): Post
    allPosts: [Post]
}

type Mutation {
    addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!
}

type Post {
    id: ID!
    author: String!
    title: String
    content: String
    url: String
    ups: Int
    downs: Int
    relatedPosts: [Post]
}
```

## リゾルバーを設定する
<a name="configuring-resolvers"></a>

Lambda のデータソースと有効な GraphQL スキーマが登録されたので、リゾルバーを使用して GraphQL フィールドを Lambda のデータソースに接続することができます。

リゾルバーを作成するには、マッピングテンプレートが必要です。マッピングテンプレートの詳細については、「[Resolver Mapping Template Overview](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)」を参照してください。

Lambda マッピングテンプレートの詳細については、「[Resolver mapping template reference for Lambda](resolver-mapping-template-reference-lambda.md#aws-appsync-resolver-mapping-template-reference-lambda)」を参照してください。

このステップでは、`getPost(id:ID!): Post`、`allPosts: [Post]`、`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!`、および `Post.relatedPosts: [Post]` の各フィールドで Lambda 関数にリゾルバーをアタッチします。

 AWS AppSync コンソールのスキーマエディタから、右側の「 **のリゾルバーをア**タッチする」を選択します`getPost(id:ID!): Post`。

次に、**[アクション]** メニューで **[ランタイムの更新]** を選択し、**[ユニットリゾルバー (VTL のみ)]** を選択します。

その後、Lambda データソースを選択します。[**request mapping template (リクエストマッピングテンプレート)**] セクションで、[**Invoke And Forward Arguments (呼び出しと引数の転送)**] を選択します。

`payload` オブジェクトを変更し、フィールド名を追加します。テンプレートは次のようになります。

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "arguments":  $utils.toJson($context.arguments)
    }
}
```

[**response mapping template (レスポンスマッピングテンプレート)**] セクションで、[**Return Lambda Result (Lambda 関数の結果を返す)**] を選択します。

この場合、ベーステンプレートをそのまま使用します。次のようになります。

```
$utils.toJson($context.result)
```

**[保存]** を選択します。最初のリゾルバーが正常に追加されました。以下のように、残りのフィールドについてこの操作を繰り返します。

`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!` リクエストマッピングテンプレートについて

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "addPost",
        "arguments":  $utils.toJson($context.arguments)
    }
}
```

`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!` レスポンスマッピングテンプレートについて

```
$utils.toJson($context.result)
```

`allPosts: [Post]` リクエストマッピングテンプレートについて

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "allPosts"
    }
}
```

`allPosts: [Post]` レスポンスマッピングテンプレートについて

```
$utils.toJson($context.result)
```

`Post.relatedPosts: [Post]` リクエストマッピングテンプレートについて

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "relatedPosts",
        "source":  $utils.toJson($context.source)
    }
}
```

`Post.relatedPosts: [Post]` レスポンスマッピングテンプレートについて

```
$utils.toJson($context.result)
```

## GraphQL API をテストする
<a name="testing-your-graphql-api"></a>

これで Lambda 関数が GraphQL リゾルバーに接続されたので、コンソールまたはクライアントアプリケーションを使用してミューテーションまたはクエリが実行できます。

 AWS AppSync コンソールの左側でクエリを選択し****、次のコードを貼り付けます。

### addPost ミューテーション
<a name="addpost-mutation"></a>

```
mutation addPost {
    addPost(
        id: 6
        author: "Author6"
        title: "Sixth book"
        url: "https://www.amazon.com/"
        content: "This is the book is a tutorial for using GraphQL with AWS AppSync."
    ) {
        id
        author
        title
        content
        url
        ups
        downs
    }
}
```

### getPost クエリ
<a name="getpost-query"></a>

```
query getPost {
    getPost(id: "2") {
        id
        author
        title
        content
        url
        ups
        downs
    }
}
```

### allPosts クエリ
<a name="allposts-query"></a>

```
query allPosts {
    allPosts {
        id
        author
        title
        content
        url
        ups
        downs
        relatedPosts {
            id
            title
        }
    }
}
```

## エラーを返す
<a name="returning-errors"></a>

指定したフィールドの解決でエラーが発生する場合があります。 AWS AppSync を使用すると、次のソースからエラーを生成できます。
+ リクエストまたはレスポンスのマッピングテンプレート
+ Lambda function

### マッピングテンプレートからの場合
<a name="from-the-mapping-template"></a>

Velocity Template Language (VTL) テンプレートから `$utils.error` ヘルパーメソッドを使用して故意にエラーを発生させることができます。これは引数として、`errorMessage`、`errorType`、および必要に応じて `data` の各値を含みます。`data` は、エラーの発生時にクライアントに追加のデータを返す場合に利用できます。`data` オブジェクトは GraphQL の最終レスポンスで `errors` に追加されます。

次の例では、`Post.relatedPosts: [Post]` レスポンスマッピングテンプレートでそれを使用する方法を示しています。

```
$utils.error("Failed to fetch relatedPosts", "LambdaFailure", $context.result)
```

これにより、以下のような GraphQL レスポンスが生成されます。

```
{
    "data": {
        "allPosts": [
            {
                "id": "2",
                "title": "Second book",
                "relatedPosts": null
            },
            ...
        ]
    },
    "errors": [
        {
            "path": [
                "allPosts",
                0,
                "relatedPosts"
            ],
            "errorType": "LambdaFailure",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ],
            "message": "Failed to fetch relatedPosts",
            "data": [
                {
                  "id": "2",
                  "title": "Second book"
                },
                {
                  "id": "1",
                  "title": "First book"
                }
            ]
        }
    ]
}
```

この場合、エラーおよび `errorMessage`、`errorType`、`data` が `data.errors[0]` オブジェクトに存在するため、`allPosts[0].relatedPosts` は *null* になります。

### Lambda 関数から
<a name="from-the-lam-function"></a>

AWS AppSync は、Lambda 関数がスローするエラーも理解します。Lambda プログラミングモデルを使用し、*処理される*エラーを発生させることができます。Lambda 関数がエラーをスローした場合、 AWS AppSync は現在のフィールドの解決に失敗します。Lambda から返されたエラーメッセージのみがレスポンスに設定されます。また現在のところ、Lambda 関数からエラーを発生させて、クライアントにエラー関連以外のデータを渡すことはできません。

 **注**: Lambda 関数が*未処理*のエラーを発生させた場合、 AWS AppSync は Lambda が設定したエラーメッセージを使用します。

以下の Lambda 関数はエラーを発生させます。

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    callback("I fail. Always.");
};
```

これにより、以下のような GraphQL レスポンスが返されます。

```
{
    "data": {
        "allPosts": [
            {
                "id": "2",
                "title": "Second book",
                "relatedPosts": null
            },
            ...
        ]
    },
    "errors": [
        {
            "path": [
                "allPosts",
                0,
                "relatedPosts"
            ],
            "errorType": "Lambda:Handled",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ],
            "message": "I fail. Always."
        }
    ]
}
```

## 高度なユースケース: バッチ処理
<a name="advanced-use-case-batching"></a>

この例の Lambda 関数には、指定した投稿に関連する投稿のリストを返す `relatedPosts` フィールドが含まれています。この例のクエリでは、Lambda 関数からの `allPosts` フィールドの呼び出しにより 5 件の投稿が返されます。返された各投稿に対して `relatedPosts` の解決も指定しているので、`relatedPosts` フィールドの処理が続けて 5 回呼び出されます。

```
query allPosts {
    allPosts {   // 1 Lambda invocation - yields 5 Posts
        id
        author
        title
        content
        url
        ups
        downs
        relatedPosts {   // 5 Lambda invocations - each yields 5 posts
            id
            title
        }
    }
}
```

この例では大して意味がないように思われますが、こうした余分な取得処理が積み重なることで、アプリケーションに急速に害をなす可能性があります。

同じクエリで返された関連する `Posts` について、再度 `relatedPosts` を取得すると、呼び出しの数は大幅に増加します。

```
query allPosts {
    allPosts {   // 1 Lambda invocation - yields 5 Posts
        id
        author
        title
        content
        url
        ups
        downs
        relatedPosts {   // 5 Lambda invocations - each yield 5 posts = 5 x 5 Posts
            id
            title
            relatedPosts {  // 5 x 5 Lambda invocations - each yield 5 posts = 25 x 5 Posts
                id
                title
                author
            }
        }
    }
}
```

この比較的単純なクエリでは、 AWS AppSync は Lambda 関数を 1 \$1 5 \$1 25 = 31 回呼び出します。

これはよくある課題であり、N\$11 問題と呼ばれます (この例では、N = 5)。これによりアプリケーションのレイテンシーとコストが増大します。

この問題を解決する 1 つの方法は、同様なフィールドのリゾルバーリクエストを同時にバッチ処理することです。この例では、Lambda 関数は指定された 1 つの投稿に関連する投稿のリストを解決するのではなく、指定された一連の投稿に関連する投稿のリストを解決できます。

これを示すため、`Post.relatedPosts: [Post]` リゾルバーをバッチ処理が有効なリゾルバーに切り替えます。

 AWS AppSync コンソールの右側で、既存の`Post.relatedPosts: [Post]`リゾルバーを選択します。リクエストマッピングテンプレートを次のように変更します。

```
{
    "version": "2017-02-28",
    "operation": "BatchInvoke",
    "payload": {
        "field": "relatedPosts",
        "source":  $utils.toJson($context.source)
    }
}
```

`operation` フィールドのみを `Invoke` から `BatchInvoke` に変更します。ペイロードフィールドはテンプレートで指定した内容の配列になっています。この例では、Lambda 関数は、入力として以下を受け取ります。

```
[
    {
        "field": "relatedPosts",
        "source": {
            "id": 1
        }
    },
    {
        "field": "relatedPosts",
        "source": {
            "id": 2
        }
    },
    ...
]
```

リクエストマッピングテンプレートで `BatchInvoke` を指定した場合、Lambda 関数はリクエストのリストを受け取り、結果のリストを返します。

具体的には、 AWS AppSync がそれに応じて結果を一致できるように、結果のリストがリクエストペイロードエントリのサイズと順序と一致する必要があります。

このバッチ処理の例では、Lambda 関数は次のように一連の結果を返します。

```
[
    [{"id":"2","title":"Second book"}, {"id":"3","title":"Third book"}],   // relatedPosts for id=1
    [{"id":"3","title":"Third book"}]                                                             // relatedPosts for id=2
]
```

次の Node.js の Lambda 関数は、`Post.relatedPosts` フィールドに対してこのバッチ処理機能を次のように実行します。

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    var posts = {
         "1": {"id": "1", "title": "First book", "author": "Author1", "url": "https://amazon.com/", "content": "SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1", "ups": "100", "downs": "10"},
         "2": {"id": "2", "title": "Second book", "author": "Author2", "url": "https://amazon.com", "content": "SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT", "ups": "100", "downs": "10"},
         "3": {"id": "3", "title": "Third book", "author": "Author3", "url": null, "content": null, "ups": null, "downs": null },
         "4": {"id": "4", "title": "Fourth book", "author": "Author4", "url": "https://www.amazon.com/", "content": "SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4", "ups": "1000", "downs": "0"},
         "5": {"id": "5", "title": "Fifth book", "author": "Author5", "url": "https://www.amazon.com/", "content": "SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT", "ups": "50", "downs": "0"} };

    var relatedPosts = {
        "1": [posts['4']],
        "2": [posts['3'], posts['5']],
        "3": [posts['2'], posts['1']],
        "4": [posts['2'], posts['1']],
        "5": []
    };

    console.log("Got a BatchInvoke Request. The payload has %d items to resolve.", event.length);
    // event is now an array
    var field = event[0].field;
    switch(field) {
        case "relatedPosts":
            var results = [];
            // the response MUST contain the same number
            // of entries as the payload array
            for (var i=0; i< event.length; i++) {
                console.log("post {}", JSON.stringify(event[i].source));
                results.push(relatedPosts[event[i].source.id]);
            }
            console.log("results {}", JSON.stringify(results));
            callback(null, results);
            break;
        default:
            callback("Unknown field, unable to resolve" + field, null);
            break;
    }
};
```

### 個々のエラーを返す
<a name="returning-individual-errors"></a>

Lambda 関数から単一のエラーを返せることや、マッピングテンプレートから 1 つのエラーを生成できることは以前の例で説明しました。バッチ処理を呼び出した場合、Lambda 関数からエラーが発生すると、バッチ処理全体が失敗としてフラグ付けされます。これは、データストアとの接続が切れた場合など、回復不可能なエラーが発生するシナリオでは問題ないかもしれません。ここでは、バッチ処理の一部が成功し、他が失敗した場合、エラーと有効なデータの両方を返すことができます。 AWS AppSync はバッチの元のサイズに一致する要素を一覧表示するためにバッチレスポンスを必要とするため、有効なデータをエラーと区別できるデータ構造を定義する必要があります。

例えば、関連する一連の投稿が返されることを Lambda 関数が期待している場合には、`Response` オブジェクトのリストを返すように選択できます。この場合、各オブジェクトに任意の *data*、*errorMessage*、および *errorType* フィールドが含まれます。*errorMessage* フィールドが存在する場合は、エラーが発生したことを意味します。

次のコードは Lambda 関数の更新方法を示しています。

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    var posts = {
         "1": {"id": "1", "title": "First book", "author": "Author1", "url": "https://amazon.com/", "content": "SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1", "ups": "100", "downs": "10"},
         "2": {"id": "2", "title": "Second book", "author": "Author2", "url": "https://amazon.com", "content": "SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT", "ups": "100", "downs": "10"},
         "3": {"id": "3", "title": "Third book", "author": "Author3", "url": null, "content": null, "ups": null, "downs": null },
         "4": {"id": "4", "title": "Fourth book", "author": "Author4", "url": "https://www.amazon.com/", "content": "SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4", "ups": "1000", "downs": "0"},
         "5": {"id": "5", "title": "Fifth book", "author": "Author5", "url": "https://www.amazon.com/", "content": "SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT", "ups": "50", "downs": "0"} };

    var relatedPosts = {
        "1": [posts['4']],
        "2": [posts['3'], posts['5']],
        "3": [posts['2'], posts['1']],
        "4": [posts['2'], posts['1']],
        "5": []
    };

    console.log("Got a BatchInvoke Request. The payload has %d items to resolve.", event.length);
    // event is now an array
    var field = event[0].field;
    switch(field) {
        case "relatedPosts":
            var results = [];
            results.push({ 'data': relatedPosts['1'] });
            results.push({ 'data': relatedPosts['2'] });
            results.push({ 'data': null, 'errorMessage': 'Error Happened', 'errorType': 'ERROR' });
            results.push(null);
            results.push({ 'data': relatedPosts['3'], 'errorMessage': 'Error Happened with last result', 'errorType': 'ERROR' });
            callback(null, results);
            break;
        default:
            callback("Unknown field, unable to resolve" + field, null);
            break;
    }
};
```

この例では、次のレスポンスマッピングテンプレートが Lambda 関数の各項目を解析し、発生するエラーがあればそれを生成します。

```
#if( $context.result && $context.result.errorMessage )
    $utils.error($context.result.errorMessage, $context.result.errorType, $context.result.data)
#else
    $utils.toJson($context.result.data)
#end
```

この例では、以下のような GraphQL レスポンスが返されます。

```
{
  "data": {
    "allPosts": [
      {
        "id": "1",
        "relatedPostsPartialErrors": [
          {
            "id": "4",
            "title": "Fourth book"
          }
        ]
      },
      {
        "id": "2",
        "relatedPostsPartialErrors": [
          {
            "id": "3",
            "title": "Third book"
          },
          {
            "id": "5",
            "title": "Fifth book"
          }
        ]
      },
      {
        "id": "3",
        "relatedPostsPartialErrors": null
      },
      {
        "id": "4",
        "relatedPostsPartialErrors": null
      },
      {
        "id": "5",
        "relatedPostsPartialErrors": null
      }
    ]
  },
  "errors": [
    {
      "path": [
        "allPosts",
        2,
        "relatedPostsPartialErrors"
      ],
      "errorType": "ERROR",
      "locations": [
        {
          "line": 4,
          "column": 9
        }
      ],
      "message": "Error Happened"
    },
    {
      "path": [
        "allPosts",
        4,
        "relatedPostsPartialErrors"
      ],
      "data": [
        {
          "id": "2",
          "title": "Second book"
        },
        {
          "id": "1",
          "title": "First book"
        }
      ],
      "errorType": "ERROR",
      "locations": [
        {
          "line": 4,
          "column": 9
        }
      ],
      "message": "Error Happened with last result"
    }
  ]
}
```

### 最大バッチサイズの設定
<a name="configure-max-batch-size"></a>

デフォルトでは、 を使用する場合`BatchInvoke`、 AWS AppSync は最大 5 つの項目のバッチで Lambda 関数にリクエストを送信します。Lambda リゾルバーの最大バッチサイズを設定できます。

リゾルバーで最大バッチサイズを設定するには、 AWS Command Line Interface () で次のコマンドを使用しますAWS CLI。

```
$ aws appsync create-resolver --api-id <api-id> --type-name Query --field-name relatedPosts \
 --request-mapping-template "<template>" --response-mapping-template "<template>" --data-source-name "<lambda-datasource>" \ 
 --max-batch-size X
```

**注記**  
リクエストマッピングテンプレートを提供するときは、バッチ処理を使用する `BatchInvoke` オペレーションを使用する必要があります。

次のコマンドを使用して、ダイレクト Lambda リゾルバーのバッチ処理を有効にして設定することもできます。

```
$ aws appsync create-resolver --api-id <api-id> --type-name Query --field-name relatedPosts \
 --data-source-name "<lambda-datasource>" \ 
 --max-batch-size X
```

### VTL テンプレートによる最大バッチサイズ設定
<a name="configure-max-batch-size-vtl"></a>

VTL のリクエスト内テンプレートがある Lambda リゾルバーの場合、最大バッチサイズは VTL の `BatchInvoke` オペレーションとして直接指定しない限り、効果がありません。同様に、トップレベルのミューテーションを実行する場合、GraphQL 仕様では並列ミューテーションを順次実行する必要があるため、ミューテーションのバッチ処理は行われません。

例として、次のミューテーションをとりあげます。

```
type Mutation {
    putItem(input: Item): Item
    putItems(inputs: [Item]): [Item]
}
```

最初のミューテーションを使うと、以下のスニペットに示すように 10 個の `Items` を作成できます。

```
mutation MyMutation {
    v1: putItem($someItem1) {
        id,
        name
    }
    v2: putItem($someItem2) {
        id,
        name
    }
    v3: putItem($someItem3) {
        id,
        name
    } 
    v4: putItem($someItem4) {
        id,
        name
    }
    v5: putItem($someItem5) {
        id,
        name
    }
    v6: putItem($someItem6) {
        id,
        name
    } 
    v7: putItem($someItem7) {
        id,
        name
    }
    v8: putItem($someItem8) {
        id,
        name
    }
    v9: putItem($someItem9) {
        id,
        name
    }
    v10: putItem($someItem10) {
        id,
        name
    }
}
```

この例では、Lambda Resolver の最大バッチサイズが 10 に設定されていても、`Items` は 10 の のグループでバッチ処理されません。代わりに、GraphQL の仕様に従って順番に実行されます。

実際にバッチミューテーションを実行するには、以下の例のように 2 つ目のミューテーションを使うといいでしょう。

```
mutation MyMutation {
    putItems([$someItem1, $someItem2, $someItem3,$someItem4, $someItem5, $someItem6, 
    $someItem7, $someItem8, $someItem9, $someItem10]) {
    id,
    name
    }
}
```

ダイレクト Lambda リゾルバーでのバッチ処理の使用方法については、[ダイレクトLambda リゾルバー](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers) を参照してください。