

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

# 创建基本查询（VTL）
<a name="configuring-resolvers"></a>

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

GraphQL 解析器将类型的架构中的字段连接到数据来源。解析器是满足请求的机制。 AWS AppSync 无需编写任何代码，即可自动创建和连接架构中的解析器，或者创建架构并从现有表连接解析器。

 AWS AppSync 用于将 GraphQL 表达式 JavaScript 转换为数据源可以使用的格式的解析器。或者，可以使用 [Apache Velocity 模板语言 (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. 在**APIs 控制面板**中，选择你的 GraphQL API。

   1. 在**侧边栏**中，选择**架构**。

1. 在页面右侧，具有一个名为**解析器**的窗口。该框包含页面左侧的**架构**窗口中定义的类型和字段列表。您可以将解析器附加到字段。例如，在 **Query** 类型下面，选择 `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 操作返回一个项目，它将是 `$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. 要修改解析器的字段 and/or 映射模板，请运行[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. 在**APIs 控制面板**中，选择你的 GraphQL API。

   1. 在**侧边栏**中，选择**架构**。

1. 在 **Mutation** 类型下面，选择 `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 操作。上一示例使用 `id` 键将记录存储在 DynamoDB 中，该键是从变更参数中作为 `$ctx.args.id` 传递的。您传递的所有其他字段使用 `$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 ]

您也可以使用 “[创建您的第一个解析器](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver)” 部分中的命令以及本节中的参数详细信息来执行此操作。 APIs 

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

您也可以在 CLI 中使用[创建您的第一个解析器](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver)一节中的命令以及本节中的参数详细信息执行该操作。

------

此时，如果您不使用高级解析器，您可以开始使用 GraphQL API，如[使用 API](using-your-api.md#aws-appsync-using-your-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))
}
```

对于这个分页使用案例，响应映射不只是简单的传递，因为它必须包含*光标*（这样客户端才知道下次从哪一页开始）以及结果集。映射模板如下所示：

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

以上响应映射模板中的字段必须与 `TodoConnection` 类型中定义的字段匹配。

如果存在以下关系：您具有 `Comments` 表并且要解析 `Todo` 类型（返回 `[Comment]` 类型）的 Comments 字段，您可以使用映射模板以对第二个表运行查询。为此，您必须已为 `Comments` 表创建了一个数据来源，如[附加数据来源](attaching-a-data-source.md#aws-appsync-getting-started-build-a-schema-from-scratch)中所述。

**注意**  
我们对第二个表使用查询操作仅用于说明目的。您可以对 DynamoDB 使用其他操作。此外，您可以从其他数据源（例如 AWS Lambda 或 Amazon S OpenSearch ervice）提取数据，因为该关系由您的 GraphQL 架构控制。

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

1. 登录 AWS 管理控制台 并打开[AppSync 控制台](https://console.aws.amazon.com/appsync/)。

   1. 在**APIs 控制面板**中，选择你的 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` 表的数据来源。在此例中请求映射模板只是简单的 `PutItem`，它具有作为参数注释的特定 `todoid`，但您可以使用 `$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 ]

您也可以使用 “[创建您的第一个解析器](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver)” 部分中的命令以及本节中的参数详细信息来执行此操作。 APIs 

------
#### [ 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 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html)的指南。

使用直接 Lambda 解析器，您可以在使用数据源时避开 VTL 映射模板的使用。 AWS Lambda AWS AppSync 可以为您的 Lambda 函数提供默认负载，以及从 Lambda 函数的响应到 GraphQL 类型的默认转换。您可以选择提供请求模板、响应模板，或者两者都不提供， 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. 在**APIs 控制面板**中，选择你的 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. `lambda-config`，即控制台示例中的**函数 ARN**。
**注意**  
必须配置其他参数（例如 `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 数据源并设置相应的 IAM 角色 AWS AppSync 以允许调用该函数后，您可以将其链接到解析器或管道函数。

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

1. 登录 AWS 管理控制台 并打开[AppSync控制台](https://console.aws.amazon.com/appsync/)。

   1. 在**APIs 控制面板**中，选择你的 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中出现一些其他行为：
+ 禁用映射模板 AWS AppSync 即表示您接受 Di [rect Lambda](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers) 解析器参考中指定的默认数据转换。
+ 通过禁用请求映射模板，您的 Lambda 数据来源将接收包含整个[上下文](resolver-context-reference.md)对象的负载。
+ 通过禁用响应映射模板，将转换您的 Lambda 调用结果，具体取决于请求映射模板版本或是否还禁用了请求映射模板。

# 在 AWS AppSync (VTL) 中测试和调试解析器
<a name="test-debug-resolvers"></a>

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

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` 对象，其中包含有关请求的信息。其中包括来自客户端的参数、身份信息以及 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. 在**APIs 控制面板**中，选择你的 GraphQL API。

   1. 在**侧边栏**中，选择**架构**。

1. 如果您尚未在类型下面的字段旁边选择**附加**以添加解析器，请执行该操作。

   有关如何构建完整解析器的更多信息，请参阅[配置解析器](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html)。

   否则，选择已位于字段中的解析器。

1. 在**编辑解析器**页面顶部，选择**选择测试上下文**，然后选择**创建新上下文**。

1. 选择一个示例上下文对象，或者在下面的**执行上下文**窗口中手动填充 JSON。

1. 输入**测试上下文名称**。

1. 选择**保存**按钮。

1. 在**编辑解析器**页面顶部，选择**运行测试**。

举一个更实际的例子，假设您具有一个存储 GraphQL 类型 `Dog` 的应用程序，该应用程序自动为对象生成 ID 并将其存储在 Amazon DynamoDB 中。您还希望通过 GraphQL 变更参数写入一些值，并仅允许特定用户查看响应。下面显示了架构的外观：

```
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's 测试映射模板 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 SDKs](https://aws.amazon.com/tools/)。例如，以上一节中的`Dog`架构及其 request/response 映射模板为例。通过在本地工作站上使用 CLI，将请求模板保存到名为 `request.vtl` 的文件中，然后将 `context` 对象保存到名为 `context.json` 的文件中。从 Shell 中，运行以下命令：

```
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。以下是使用适用于 JavaScript V2 的 AWS SDK 的示例：

```
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 查询、突变和订阅，并将每个请求的实时日志数据流回查询编辑器进行实时调试。对于订阅而言，日志显示连接时间信息。

要执行此操作，您需要提前启用 Amazon CloudWatch 日志，如[监控和日志](monitoring.md#aws-appsync-monitoring)中所述。接下来，在 AWS AppSync 控制台中选择 “**查询**” 选项卡，然后输入有效的 GraphQL 查询。在右下部分中，单击并拖动**日志**窗口以打开“日志”视图。在页面顶部，选择“播放”箭头图标运行您的 GraphQL 查询。片刻之后，此操作的完整请求和响应日志将流式传输到控制台的这一部分，之后您可以在控制台中进行查看。

# 在 AWS AppSync (VTL) 中配置和使用管道解析器
<a name="pipeline-resolvers"></a>

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

AWS AppSync 在 GraphQL 字段上执行解析器。在某些情况下，应用程序需要执行多个操作以解析单个 GraphQL 字段。通过使用管道解析器，开发人员现在可以编写称为“函数”的操作并按顺序执行它们。例如，管道解析器对于需要在获取字段数据之前执行授权检查的应用程序非常有用。

管道解析器由**之前** 映射模板、**之后** 映射模板和一组函数组成。每个函数具有对数据来源执行的**请求**映射模板和**响应**映射模板。由于管道解析器将执行委托给函数列表，因此它不会链接到任何数据来源。单位解析器和函数是对数据来源执行操作的基元。有关更多信息，请参阅[解析器映射模板概述](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
}
```

我们将一个管道解析器连接到 **Mutation** 类型的 **signUp** 字段。在右侧的 **Mutation** 类型中，选择 `signUp` 变更字段旁边的**附加**。在“创建解析器”页面上，单击**操作**，然后单击**更新运行时**。依次选择`Pipeline Resolver`、`VTL` 和**更新**。该页面现在应显示三个部分：**之前映射模板**文本区域、**函数**部分和**之后映射模板**文本区域。

我们的管道解析器通过先验证电子邮件地址输入，然后将用户保存在系统中来注册用户。我们将电子邮件验证封装在 **validateEmail** 函数中，并将用户保存在 **saveUser** 函数中。首先执行 **validateEmail** 函数，如果电子邮件有效，则执行 **saveUser** 函数。

执行流将如下所示：

1. Mutation.signUp 解析器请求映射模板

1. validateEmail 函数

1. saveUser 函数

1. Mutation.signUp 解析器响应映射模板

由于我们可能在 API 上的其他解析器中重复使用 **validateEmail** 函数，因此，我们希望避免访问 `$ctx.args`，因为它们将从一个 GraphQL 字段更改为另一个字段。相反，我们可以使用 `$ctx.stash` 存储 `signUp(input: Signup)` 输入字段参数中的电子邮件属性。

**之前**映射模板：

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

控制台提供一个我们将使用的默认传递**之后**映射模板：

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

选择**创建**或**保存**以更新解析器。

## 步骤 2：创建函数
<a name="create-a-function"></a>

从管道解析器页面的**函数**部分中，单击**添加函数**，然后单击**创建新函数**。也可以在不通过解析器页面的情况下创建函数；要执行此操作，请在 AWS AppSync控制台中转到 “**函数**” 页面。选择**创建函数**按钮。让我们创建一个函数来检查电子邮件是否有效并来自特定域。如果电子邮件无效，该函数会引发一个错误。否则，它将转发接收到的任何输入。

在新函数页面上，选择**操作**，然后选择**更新运行时**。选择 `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 控制台中，转到 “**查询**” 页面。在资源管理器中，确保您正在使用变更。如果不是，请在下拉列表中选择`Mutation`，然后选择 `+`。输入以下查询：

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

它应返回如下内容：

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

我们已成功注册用户，并使用管道解析器验证了输入电子邮件。要遵循有关管道解析器的更完整的教程，您可以转到[教程：管道解析器](tutorial-pipeline-resolvers.md#aws-appsync-tutorial-pipeline-resolvers) 