

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

# 在 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) 