管道解析程序 - AWS AppSync
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

管道解析程序

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

管道解析程序剖析

管道解析程序由一个之前映射模板、一个之后映射模板以及函数列表组成。每个函数都有一个针对数据源执行的请求响应映射模板。由于管道解析程序将执行委托给函数列表,因此它不会链接到任何数据源。单元解析程序和函数是对数据源执行操作的基元。有关更多信息,请参阅解析程序映射模板概述

之前映射模板

管道解析程序的请求映射模板(也称为之前步骤)允许在执行定义的函数之前执行某些准备逻辑。

函数列表

管道解析程序将按顺序运行的函数的列表。管道解析程序请求映射模板评估的结果可供第一个函数用作 $ctx.prev.result。每个函数输出可供下一个函数用作 $ctx.prev.result

之后映射模板

管道解析程序的响应映射模板(也称为之后步骤)允许从最后一个函数的输出到预期的 GraphQL 字段类型执行某些最后映射逻辑。函数列表中最后一个函数的输出可在管道解析程序映射模板中用作 $ctx.prev.result$ctx.result

执行流

给定一个由 2 个函数组成的管道解析程序,下面的列表表示调用解析程序时的执行流:

  1. 管道解析程序之前映射模板

  2. 函数 1:函数请求映射模板

  3. 函数 1:数据源调用

  4. 函数 1:函数响应映射模板

  5. 函数 2:函数请求映射模板

  6. 函数 2:数据源调用

  7. 函数 2:函数响应映射模板

  8. 管道解析程序之后映射模板

管道解析程序执行流是单向的,并在解析程序上静态定义。

有用的 Apache Velocity 模板语言 (VTL) 实用程序

随着应用程序复杂性的增加,VTL 实用工具和指令在这里有助于提高开发效率。在使用管道解析程序时,以下实用工具可为您提供帮助。

$ctx.stash

该存储是可供每个解析程序和函数映射模板内部使用的映射。同一存储实例通过单个解析程序生效。这意味着您可以使用存储来跨请求和响应映射模板以及管道解析程序中的函数传递任意数据。该存储公开与 Java Map 数据结构相同的方法。

$ctx.prev.result

$ctx.prev.result 表示已在管道中执行的上一个操作的结果。如果上一个操作是管道解析程序请求映射模板,则 $ctx.prev.result 表示模板评估的输出,并且可供链中的第一个函数使用。如果上一个操作是第一个函数,则 $ctx.prev.result 表示第一个函数的输出,并且可供管道中的第二个函数使用。如果上一个操作是最后一个函数,则 $ctx.prev.result 表示第一个函数的输出,并且可供管道解析程序响应映射模板使用。

#return(data: Object)

如果您需要从任何映射模板提前返回,#return(data: Object) 指令会很有用。#return(data: Object) 类似于编程语言中的 return 关键字,因为它会从最近的逻辑范围块返回。这意味着在解析程序映射模板中使用 #return 会从解析程序返回。在解析程序映射模板中使用 #return(data: Object) 会在 GraphQL 字段上设置 data。此外,从函数映射模板使用 #return(data: Object) 会从函数返回,并继续执行到管道中的下一个函数或解析程序响应映射模板。

#return

#return(data: Object) 相同,但将返回 null

$util.error

$util.error 实用工具对于引发字段错误很有用。在函数映射模板中使用 $util.error 会立即引发字段错误,从而阻止执行后续函数。有关更多详细信息及其他 $util.error 签名,请访问解析程序映射模板实用工具参考

$util.appendError

$util.appendError 类似于 $util.error(),主要区别在于前者不会中断映射模板的评估。相反,它指示该字段存在错误,但允许评估模板并因此会返回数据。在函数中使用 $util.appendError 将不会中断管道的执行流。有关更多详细信息及其他 $util.error 签名,请访问解析程序映射模板实用工具参考

创建管道解析程序

在 AWS AppSync 控制台中,转至 Schema (架构) 页面。

保存以下架构:

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 字段旁边的 Attach resolver (附加解析程序)。在 Create Resolver (创建解析程序) 页面上,单击 Switch to Pipeline (切换到管道) 按钮。该页面现在应显示 3 个部分,一个 Before Mapping Template (之前映射模板) 文本区域、一个 Functions (函数) 部分和一个 After Mapping template (之后映射模板) 文本区域。

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

执行流将如下所示:

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

  2. validateEmail 函数

  3. saveUser 函数

  4. 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)

创建函数

在管道解析程序页面上的 Functions (函数) 部分中,单击 Create Function (创建函数)。也可以在不通过解析程序页面的情况下创建函数,为此,请在 AWS AppSync 控制台中,转到 Functions (函数) 页面。选择 Create Function (创建函数) 按钮。让我们创建一个函数来检查电子邮件是否有效并来自特定域。如果电子邮件无效,该函数会引发一个错误。否则,它将转发接收到的任何输入。

在函数页面上选择 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 函数。

向管道解析程序添加函数

我们的函数应已自动添加到刚刚创建的管道解析程序。如果您碰巧通过控制台 Functions (函数) 页面创建了函数,则可以单击解析程序页面上的 Add Function (添加函数) 来附加它们。将 validateEmailsaveUser 函数添加到解析程序。validateEmail 函数应放在 saveUser 函数之前。在添加更多函数时,您可以使用向上和向下箭头来重新组织函数的执行顺序。

执行查询

在 AWS AppSync 控制台中,转到 Queries (查询) 页面。输入以下查询:

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

应返回如下内容:

{ "data": { "signUp": { "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc", "username": "nadia" } } }

我们已成功注册用户,并使用管道解析程序验证了输入电子邮件。要遵循有关管道解析程序的更完整的教程,您可以转到教程:管道解析程序