

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在中使用 AWS Lambda 解析器 AWS AppSync
<a name="tutorial-lambda-resolvers"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html)的指南。

你可以 AWS Lambda 和一起使用 AWS AppSync 来解析任何 GraphQL 字段。例如，GraphQL 查询可能会向 Amazon Relational Database Service (Amazon RDS) 实例发送调用，而 GraphQL 变更可能会写入到 Amazon Kinesis 流。在本节中，我们说明了如何编写 Lambda 函数，以根据 GraphQL 字段操作调用执行业务逻辑。

## 创建 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 检索文章，添加文章，检索文章列表以及获取给定文章的相关文章。

 **注意：**Lambda 函数对 `event.field` 执行 `switch` 语句以确定当前解析的字段。

使用 AWS 管理控制台或堆栈创建此 Lambda 函数。 AWS CloudFormation 要从 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)。

在该步骤中，您将一个解析器附加到以下字段的 Lambda 函数：`getPost(id:ID!): Post`、`allPosts: [Post]`、`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!` 和 `Post.relatedPosts: [Post]`。

在 AWS AppSync 控制台的架构编辑器中，在右侧选择**连接解析器**。`getPost(id:ID!): Post`

然后，在**操作**菜单中，选择**更新运行时**，然后选择**单位解析器 (仅限 VTL)**。

然后，选择您的 Lambda 数据来源。在**请求映射模板**部分中，选择 **Invoke And Forward Arguments (调用并转发参数)**。

修改 `payload` 对象，添加字段名称。您的模板应该类似以下内容：

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

在**响应映射模板**部分中，选择 **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 控制台的左侧，选择 **Quer** ies，然后粘贴以下代码：

### 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 函数

### 从映射模板
<a name="from-the-mapping-template"></a>

要故意引发错误，您可以使用 Velocity 模板语言 (VTL) 模板中的 `$utils.error` 帮助程序方法。它可接收 `errorMessage`、`errorType` 以及可选的 `data` 值作为参数。出现错误后，`data` 对于将额外的数据返回客户端很有用。在 GraphQL 最终响应中，`data` 对象将添加到 `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"
                }
            ]
        }
    ]
}
```

由于出现错误，导致 `allPosts[0].relatedPosts` 为 *null*，而 `data.errors[0]` 对象中存在 `errorMessage`、`errorType` 和 `data`。

### 从 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），会导致延迟增加，以及应用程序费用提升。

我们解决此问题的方式是批处理类似的字段解析器请求。在该示例中，Lambda 函数可能会解析给定批次的文章的相关文章列表，而不是让 Lambda 函数解析单个给定文章的相关文章列表。

为了演示此操作，让我们将 `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 函数中返回单个错误，或者从映射模板中引发错误。对于批处理调用，从 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 会将请求分批发送到您的 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 解析器中将最大批次大小设置为 10，也不会以 10 为一组对 `Items` 进行批处理，而是根据 GraphQL 规范按顺序执行它们。

要执行实际的批处理变更，您可以按照以下示例使用第二个变更：

```
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)。