

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

# 创建基本查询 (JavaScript)
<a name="configuring-resolvers-js"></a>

GraphQL 解析器将类型的架构中的字段连接到数据来源。解析器是用于完成请求的机制。

正在 AWS AppSync 使用解析器 JavaScript 将 GraphQL 表达式转换为数据源可以使用的格式。或者，可以使用 [Apache Velocity 模板语言 (VTL)](https://velocity.apache.org/engine/2.0/vtl-reference.html) 编写映射模板，以将 GraphQL 表达式转换为数据来源可使用的格式。

本节介绍如何使用 JavaScript配置解析器。解[析器教程 (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html) 部分提供了有关如何使用实现解析器的深入教程。 JavaScript[Resolver 参考 (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html) 部分解释了可与解 JavaScript 析器一起使用的实用程序操作。

我们建议您在尝试使用任何上述教程之前先遵循本指南。

在本节中，我们将介绍如何为查询和变更创建和配置解析器。

**注意**  
本指南假设您已创建架构并至少具有一个查询或变更。如果您要获取订阅（实时数据），请参阅[本](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)指南。

在本节中，我们提供一些配置解析器的常规步骤以及一个使用以下架构的示例：

```
// schema.graphql file

input CreatePostInput {
  title: String
  date: AWSDateTime
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
}

type Mutation {
  createPost(input: CreatePostInput!): Post
}

type Query {
  getPost: [Post]
}
```

## 创建基本查询解析器
<a name="create-basic-query-resolver-js"></a>

本节说明了如何创建基本查询解析器。

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

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

   1. 在**APIs 控制面板**中，选择你的 GraphQL API。

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

1. 输入架构和数据来源详细信息。有关更多信息，请参阅[设计架构](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)和[附加数据来源](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)小节。

1. 在**架构**编辑器旁边，具有一个名为**解析器**的窗口。该框包含**架构**窗口中定义的类型和字段列表。您可以将解析器附加到字段。您很可能会将解析器附加到字段操作。在本节中，我们将了解简单的查询配置。在 **Query** 类型下面，选择您的查询字段旁边的**附加**。

1. 在**附加解析器**页面上的**解析器类型**下面，您可以在管道解析器和单位解析器之间进行选择。有关这些类型的更多信息，请参阅[解析器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)。本指南将使用`pipeline resolvers`。
**提示**  
在创建管道解析器时，您的数据来源将附加到管道函数。函数是在您创建管道解析器本身之后创建的，这就是为什么在该页面中没有设置数据来源的选项。如果您使用单位解析器，则数据来源直接绑定到解析器，因此，您可以在该页面中设置数据来源。

   对于 **Resolver 运行时**`APPSYNC_JS`，选择启用 JavaScript 运行时。

1. 您可以为该 API 启用[缓存](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html)。我们建议暂时关闭该功能。选择**创建**。

1. 在**编辑解析器**页面上，具有一个名为**解析器代码**的代码编辑器，可用于实施解析器处理程序和响应的逻辑（预备步骤和后续步骤）。有关更多信息，请参阅[JavaScript解析器概述](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。
**注意**  
在我们的示例中，我们直接将请求保留空白，并将响应设置为从[上下文](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)返回最后的数据来源结果：  

   ```
   import {util} from '@aws-appsync/utils';
   
   export function request(ctx) {
       return {};
   }
   
   export function response(ctx) {
       return ctx.prev.result;
   }
   ```

   在该部分下面，具有有一个名为**函数**的表。函数用于实施可以在多个解析器中重复使用的代码。您可以将源代码存储为函数以在需要时添加到解析器中，而不是不断重新编写或复制代码。

   函数占据了管道的操作列表中的很大部分。在解析器中使用多个函数时，您可以设置函数顺序，将按该顺序运行它们。它们在请求函数运行之后和响应函数开始之前执行。

   要添加新函数，请在**函数**下面选择**添加函数**，然后选择**创建新函数**。或者，您可能会看到一个**创建函数**按钮可供选择。

   1. 选择一个数据来源。这是解析器处理的数据来源。
**注意**  
在我们的示例中，我们为 `getPost` 附加一个解析器，它按 `id` 检索 `Post` 对象。假设我们已为该架构设置一个 DynamoDB 表。其分区键设置为 `id` 并且为空。

   1. 输入一个`Function name`。

   1. 在**函数代码**下面，您需要实施函数的行为。这可能会令人困惑，但每个函数具有自己的本地请求和响应处理程序。先运行请求，然后调用数据来源以处理请求，最后由响应处理程序处理数据来源响应。结果存储在[上下文](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)对象中。然后，运行列表中的下一个函数；如果是最后一个函数，则将其传递给后续步骤响应处理程序。
**注意**  
在我们的示例中，我们将一个解析器附加到 `getPost`，它从数据来源获取 `Post` 对象列表。我们的请求函数将从我们的表中请求数据，表将其响应传递给上下文 (ctx)，然后响应将在上下文中返回结果。 AWS AppSync的优势在于它与其他服务的互连性。 AWS 由于我们使用的是 DynamoDB，因此，我们具有[一组操作](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html)以简化此类操作。我们还具有其他数据来源类型的一些样板示例。  
我们的代码将如下所示：  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Performs a scan on the dynamodb data source
       */
      export function request(ctx) {
        return { operation: 'Scan' };
      }
      
      /**
       * return a list of scanned post items
       */
      export function response(ctx) {
        return ctx.result.items;
      }
      ```
在该步骤中，我们添加了两个函数：  
`request`：请求处理程序对数据来源执行检索操作。参数包含上下文对象 (`ctx`) 或为执行特定操作的所有解析器提供的一些数据。例如，它可能包含授权数据、解析的字段名称等。返回语句执行 [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) 操作（请参阅[此处](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html)的示例）。由于我们使用的是 DynamoDB，因此，我们可以使用该服务中的一些操作。扫描对表中的所有项目执行基本获取。该操作的结果作为 `result` 容器存储在上下文对象中，然后再传递给响应处理程序。`request` 在管道中的响应之前运行。
`response`：返回 `request` 输出的响应处理程序。参数是更新的上下文对象，返回语句是 `ctx.prev.result`。在本指南的当前阶段，您可能还不熟悉该值。`ctx` 指的是上下文对象。`prev` 指的是管道中的以前操作，也就是 `request`。`result` 包含在管道中执行解析器的结果。如果将它们放在一起，`ctx.prev.result` 将返回最后执行的操作的结果，即请求处理程序。

   1. 在完成后，选择**创建**。

1. 返回到解析器屏幕，在**函数**下面选择**添加函数**下拉列表，然后将您的函数添加到函数列表中。

1. 选择**保存**以更新解析器。

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

**添加您的函数**
+ 使用 `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)` 命令为管道解析器创建一个函数。

  您需要为该特定命令输入一些参数：

  1. 您的 API 的 `api-id`。

  1.  AWS AppSync 控制台`name`中该函数的。

  1. `data-source-name` 或函数使用的数据来源名称。它必须已创建并链接到 AWS AppSync 服务中的 GraphQL API。

  1. `runtime` 或函数的环境和语言。对于 JavaScript，名称必须为`APPSYNC_JS`，运行时必须为`1.0.0`。

  1. `code` 或函数的请求和响应处理程序。虽然您可以手动键入该内容，但将其添加到 .txt 文件（或类似格式）并作为参数传入要容易得多。
**注意**  
我们的查询代码将位于作为参数传入的文件中：  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Performs a scan on the dynamodb data source
      */
     export function request(ctx) {
       return { operation: 'Scan' };
     }
     
     /**
      * return a list of scanned post items
      */
     export function response(ctx) {
       return ctx.result.items;
     }
     ```

  示例命令可能如下所示：

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name get_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file://~/path/to/file/{filename}.{fileType}
  ```

  将在 CLI 中返回输出。示例如下：

  ```
  {
      "functionConfiguration": {
          "functionId": "ejglgvmcabdn7lx75ref4qeig4",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/ejglgvmcabdn7lx75ref4qeig4",
          "name": "get_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```
**注意**  
确保将 `functionId` 记录在某处，因为它用于将函数附加到解析器。

**创建您的解析器**
+ 运行 `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)` 命令，为 `Query` 创建一个管道函数。

  您需要为该特定命令输入一些参数：

  1. 您的 API 的 `api-id`。

  1. `type-name` 或架构中的特殊对象类型（查询、变更、订阅）。

  1. `field-name` 或要将解析器附加到的特殊对象类型中的字段操作。

  1. `kind`，它指定单位解析器或管道解析器。请将其设置为 `PIPELINE` 以启用管道函数。

  1. `pipeline-config` 或附加到解析器的函数。确保您知道函数的 `functionId` 值。列表顺序很重要。

  1. 那是`runtime`，那是 `APPSYNC_JS` (JavaScript)。`runtimeVersion` 目前是 `1.0.0`。

  1. `code`，它包含预备步骤和后续步骤处理程序。
**注意**  
我们的查询代码将位于作为参数传入的文件中：  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  示例命令可能如下所示：

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Query \
  --field-name getPost \
  --kind PIPELINE \
  --pipeline-config functions=ejglgvmcabdn7lx75ref4qeig4 \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  将在 CLI 中返回输出。示例如下：

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "getPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/getPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "ejglgvmcabdn7lx75ref4qeig4"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**提示**  
在使用 CDK 之前，我们建议您查看 CDK 的[官方文档](https://docs.aws.amazon.com/cdk/v2/guide/home.html)以及 [CD](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html) K 参考资料。 AWS AppSync  
下面列出的步骤仅显示用于添加特定资源的一般代码片段示例。这**并不**意味着，它是您的生产代码中的有效解决方案。我们还假设您已具有正常工作的应用程序。

基本应用程序需要使用以下内容：

1. 服务导入指令

1. 架构代码

1. 数据来源生成器

1. 函数代码

1. 解析器代码

从[设计您的架构](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html)和[附加数据来源](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html)小节中，我们知道堆栈文件将包含以下格式的 import 指令：

```
import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
```

**注意**  
在前面的章节中，我们只说明了如何导入 AWS AppSync 构造。在实际代码中，您必须导入更多服务才能运行应用程序。在我们的示例中，如果我们要创建一个非常简单的 CDK 应用程序，我们至少要导入该 AWS AppSync 服务以及我们的数据源，即 DynamoDB 表。我们还需要导入一些额外的构造以部署应用程序：  

```
import * as cdk from 'aws-cdk-lib';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
```
简要说明一下每个指令：  
`import * as cdk from 'aws-cdk-lib';`：用于定义 CDK 应用程序和构造，例如堆栈。它还包含一些对我们的应用程序非常有用的实用程序函数，例如处理元数据。如果您熟悉该 import 指令，但想知道为什么此处没有使用 cdk 核心库，请参阅 [Migration](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html) 页面。
`import * as appsync from 'aws-cdk-lib/aws-appsync';`：它导入 [AWS AppSync 服务](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)。
`import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';`：它导入 [DynamoDB 服务](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb-readme.html)。
`import { Construct } from 'constructs';`：我们需要使用该指令以定义根[构造](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html)。

导入类型取决于您调用的服务。我们建议查看 CDK 文档以获取示例。页面顶部的架构是 CDK 应用程序中的单独文件，显示为 `.graphql` 文件。在堆栈文件中，我们可以使用以下格式将其与新的 GraphQL 相关联：

```
const add_api = new appsync.GraphqlApi(this, 'graphQL-example', {
  name: 'my-first-api',
  schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphql')),
});
```

**注意**  
在 `add_api` 范围内，我们使用 `new` 关键字和后面的 `appsync.GraphqlApi(scope: Construct, id: string , props: GraphqlApiProps)` 添加新的 GraphQL API。我们的范围是 `this`，CFN ID 是 `graphQL-example`，我们的属性是 `my-first-api`（控制台中的 API 的名称）和 `schema.graphql`（架构文件的绝对路径）。

要添加数据来源，您必须先将数据来源添加到堆栈中。然后，您需要使用源特定的方法将其与 GraphQL API 相关联。在您创建解析器函数时，将会发生关联。同时，让我们使用一个通过 `dynamodb.Table` 创建 DynamoDB 表的示例：

```
const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
});
```

**注意**  
如果我们要在示例中使用该表，我们将添加一个 CFN ID 为 `posts-table` 且分区键为 `id (S)` 的新 DynamoDB 表。

接下来，我们需要在堆栈文件中实施解析器。以下是扫描 DynamoDB 表中的所有项目的简单查询示例：

```
const add_func = new appsync.AppsyncFunction(this, 'func-get-posts', {
  name: 'get_posts_func_1',
  add_api,
  dataSource: add_api.addDynamoDbDataSource('table-for-posts', add_ddb_table),
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return { operation: 'Scan' };
      }

      export function response(ctx) {
        return ctx.result.items;
      }
  `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
});

new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
  add_api,
  typeName: 'Query',
  fieldName: 'getPost',
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return {};
      }

      export function response(ctx) {
        return ctx.prev.result;
      }
 `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
  pipelineConfig: [add_func],
});
```

**注意**  
首先，我们创建一个名为 `add_func` 的函数。这种创建顺序可能看起来有点违背常理，但您必须在创建管道解析器本身之前在解析器中创建函数。函数采用以下格式：  

```
AppsyncFunction(scope: Construct, id: string, props: AppsyncFunctionProps)
```
我们的范围是 `this`，CFN ID 是 `func-get-posts`，属性包含实际函数详细信息。我们在属性中包含：  
 AWS AppSync 控制台中将出现的函数 (`get_posts_func_1`)。`name`
我们以前创建的 GraphQL API (`add_api`)。
数据来源；我们在其中将数据来源链接到 GraphQL API 值，然后将其附加到函数。我们获取创建的表 (`add_ddb_table`)，并使用 `GraphqlApi` 方法之一 ([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options)) 将其附加到 GraphQL API (`add_api`)。ID 值 (`table-for-posts`) 是 AWS AppSync 控制台中的数据来源的名称。有关源特定的方法列表，请参阅以下页面：  
[ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
 [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
 [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
 [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
 [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
 [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
 [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 
代码包含函数的请求和响应处理程序，这是简单的扫描和返回。
运行时系统指定我们要使用 APPSYNC\$1JS 运行时系统 1.0.0 版。请注意，这是目前唯一适用于 APPSYNC\$1JS 的版本。
接下来，我们需要将函数附加到管道解析器。我们使用以下格式创建解析器：  

```
Resolver(scope: Construct, id: string, props: ResolverProps)
```
我们的范围是 `this`，CFN ID 是 `pipeline-resolver-get-posts`，属性包含实际函数详细信息。我们在属性中包含：  
我们以前创建的 GraphQL API (`add_api`)。
特殊对象类型名称；这是一个查询操作，因此，我们直接添加了 `Query` 值。
字段名称 (`getPost`) 是架构中的 `Query` 类型下面的字段名称。
代码包含预备步骤处理程序和后续步骤处理程序。我们的示例仅返回函数执行操作后在上下文中包含的任何结果。
运行时系统指定我们要使用 APPSYNC\$1JS 运行时系统 1.0.0 版。请注意，这是目前唯一适用于 APPSYNC\$1JS 的版本。
管道配置包含对我们创建的函数 (`add_func`) 的引用。

------

为了总结此示例中发生的情况，您看到了一个实现请求和响应处理程序的 AWS AppSync 函数。该函数负责与您的数据来源进行交互。请求处理程序向其发送了一个`Scan`操作 AWS AppSync，指示其对您的 DynamoDB 数据源执行什么操作。响应处理程序返回项目列表 (`ctx.result.items`)。然后，将项目列表自动映射到 `Post` GraphQL 类型。

## 创建基本变更解析器
<a name="creating-basic-mutation-resolvers-js"></a>

本节说明了如何创建基本变更解析器。

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

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

   1. 在**APIs 控制面板**中，选择你的 GraphQL API。

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

1. 在**解析器**部分的 **Mutation** 类型下面，选择您的字段旁边的**附加**。
**注意**  
在我们的示例中，我们为 `createPost` 附加一个解析器，它将 `Post` 对象添加到我们的表中。假设我们使用上一节中的相同 DynamoDB 表。其分区键设置为 `id` 并且为空。

1. 在**附加解析器**页面上的**解析器类型**下面，选择`pipeline resolvers`。提醒一下，您可以在[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)找到有关解析器的更多信息。对于 **Resolver 运行时**`APPSYNC_JS`，选择启用 JavaScript 运行时。

1. 您可以为该 API 启用[缓存](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html)。我们建议暂时关闭该功能。选择**创建**。

1. 选择**添加函数**，然后选择**创建新函数**。或者，您可能会看到一个**创建函数**按钮可供选择。

   1. 选择您的 数据来源。这应该是使用变更处理数据的源。

   1. 输入一个`Function name`。

   1. 在**函数代码**下面，您需要实施函数的行为。这是一个变更，因此，理想情况下，请求将对调用的数据来源执行某种状态更改操作。结果由响应函数进行处理。
**注意**  
`createPost` 在表中添加或“放置”新的 `Post`，并将我们的参数作为数据。我们可能会添如下内容：  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Sends a request to `put` an item in the DynamoDB data source
       */
      export function request(ctx) {
        return {
          operation: 'PutItem',
          key: util.dynamodb.toMapValues({id: util.autoId()}),
          attributeValues: util.dynamodb.toMapValues(ctx.args.input),
        };
      }
      
      /**
       * returns the result of the `put` operation
       */
      export function response(ctx) {
        return ctx.result;
      }
      ```
在该步骤中，我们还添加了 `request` 和 `response` 函数：  
`request`：请求处理程序接受上下文以作为参数。请求处理程序返回语句执行 [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem) 命令，这是内置的 DynamoDB 操作（请参阅[此处](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html)或[此处](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.WritingData)的示例）。`PutItem` 命令获取分区 `key` 值（由 `util.autoid()` 自动生成）以及来自上下文参数输入的 `attributes`（这些是在请求中传递的值），以将 `Post` 对象添加到我们的 DynamoDB 表中。`key` 是 `id`，`attributes` 是 `date` 和 `title` 字段参数。它们通过 [https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js](https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js) 帮助程序预先设置格式以与 DynamoDB 表一起使用。
`response`：响应接受更新的上下文，并返回请求处理程序的结果。

   1. 在完成后，选择**创建**。

1. 返回到解析器屏幕，在**函数**下面选择**添加函数**下拉列表，然后将您的函数添加到函数列表中。

1. 选择**保存**以更新解析器。

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

**添加您的函数**
+ 使用 `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)` 命令为管道解析器创建一个函数。

  您需要为该特定命令输入一些参数：

  1. 您的 API 的 `api-id`。

  1.  AWS AppSync 控制台`name`中该函数的。

  1. `data-source-name` 或函数使用的数据来源名称。它必须已创建并链接到 AWS AppSync 服务中的 GraphQL API。

  1. `runtime` 或函数的环境和语言。对于 JavaScript，名称必须为`APPSYNC_JS`，运行时必须为`1.0.0`。

  1. `code` 或函数的请求和响应处理程序。虽然您可以手动键入该内容，但将其添加到 .txt 文件（或类似格式）并作为参数传入要容易得多。
**注意**  
我们的查询代码将位于作为参数传入的文件中：  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({id: util.autoId()}),
         attributeValues: util.dynamodb.toMapValues(ctx.args.input),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  示例命令可能如下所示：

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name add_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  将在 CLI 中返回输出。示例如下：

  ```
  {
      "functionConfiguration": {
          "functionId": "vulcmbfcxffiram63psb4dduoa",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/vulcmbfcxffiram63psb4dduoa",
          "name": "add_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output foes here"
      }
  }
  ```
**注意**  
确保将 `functionId` 记录在某处，因为它用于将函数附加到解析器。

**创建您的解析器**
+ 运行 `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)` 命令，为 `Mutation` 创建一个管道函数。

  您需要为该特定命令输入一些参数：

  1. 您的 API 的 `api-id`。

  1. `type-name` 或架构中的特殊对象类型（查询、变更、订阅）。

  1. `field-name` 或要将解析器附加到的特殊对象类型中的字段操作。

  1. `kind`，它指定单位解析器或管道解析器。请将其设置为 `PIPELINE` 以启用管道函数。

  1. `pipeline-config` 或附加到解析器的函数。确保您知道函数的 `functionId` 值。列表顺序很重要。

  1. 那是`runtime`，那是 `APPSYNC_JS` (JavaScript)。`runtimeVersion` 目前是 `1.0.0`。

  1. `code`，它包含预备步骤和后续步骤。
**注意**  
我们的查询代码将位于作为参数传入的文件中：  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  示例命令可能如下所示：

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Mutation \
  --field-name createPost \
  --kind PIPELINE \
  --pipeline-config functions=vulcmbfcxffiram63psb4dduoa \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  将在 CLI 中返回输出。示例如下：

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "createPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/createPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "vulcmbfcxffiram63psb4dduoa"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**提示**  
在使用 CDK 之前，我们建议您查看 CDK 的[官方文档](https://docs.aws.amazon.com/cdk/v2/guide/home.html)以及 [CD](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html) K 参考资料。 AWS AppSync  
下面列出的步骤仅显示用于添加特定资源的一般代码片段示例。这**并不**意味着，它是您的生产代码中的有效解决方案。我们还假设您已具有正常工作的应用程序。
+ 要创建变更，假设您使用同一项目，您可以将其添加到堆栈文件中，就像查询一样。以下是修改的函数和解析器，用于在表中添加新 `Post` 的变更：

  ```
  const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
    name: 'add_posts_func_1',
    add_api,
    dataSource: add_api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table),
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {
                operation: 'PutItem',
                key: util.dynamodb.toMapValues({id: util.autoId()}),
                attributeValues: util.dynamodb.toMapValues(ctx.args.input),
              };
            }
  
            export function response(ctx) {
              return ctx.result;
            }
        `), 
    runtime: appsync.FunctionRuntime.JS_1_0_0,
  });
  
  new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
    add_api,
    typeName: 'Mutation',
    fieldName: 'createPost',
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {};
            }
  
            export function response(ctx) {
              return ctx.prev.result;
            }
        `),
    runtime: appsync.FunctionRuntime.JS_1_0_0,
    pipelineConfig: [add_func_2],
  });
  ```
**注意**  
由于该变更和查询的结构相似，因此，我们仅介绍为创建变更而进行的更改。  
在该函数中，我们将 CFN ID 更改为 `func-add-post` 并将名称更改为 `add_posts_func_1`，以反映我们将 `Posts` 添加到表中的情况。在数据源中，我们在 AWS AppSync 控制台中与表 (`add_ddb_table`) 建立了新的关联，`table-for-posts-2`因为该`addDynamoDbDataSource`方法需要它。请记住，这个新的关联仍在使用我们之前创建的同一个表，但是我们现在在 AWS AppSync 控制台中有两个与它的连接：一个用于查询 as`table-for-posts`，另一个用于变异为`table-for-posts-2`。代码进行了更改以添加 `Post`，方法是自动生成其 `id` 值，并接受客户端输入以用于其余字段。  
在解析器中，我们将 id 值更改为 `pipeline-resolver-create-posts` 以反映我们将 `Posts` 添加到表中的情况。为了反映架构中的变更，类型名称更改为 `Mutation`，名称更改为 `createPost`。管道配置设置为我们的新变更函数 `add_func_2`。

------

为了总结本示例中发生的情况， AWS AppSync 自动将`createPost`字段中定义的参数从 GraphQL 架构转换为 DynamoDB 操作。该示例使用 `id` 键将记录存储在 DynamoDB 中，该键是使用我们的 `util.autoId()` 帮助程序自动创建的。您通过 AWS AppSync 控制台或其他方式发出的请求传递给上下文参数 (`ctx.args.input`) 的所有其他字段都将存储为表的属性。键和属性使用 `util.dynamodb.toMapValues(values)` 帮助程序自动映射到兼容的 DynamoDB 格式。

AWS AppSync 还支持用于编辑解析器的测试和调试工作流程。您可以在调用模板之前使用模拟 `context` 对象查看转换的模板值。或者，您可以选择在运行查询时以交互方式查看对数据来源的完整请求。有关更多信息，请参阅[测试和调试解析器 (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/test-debug-resolvers-js.html) 和[监控和日志记录](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html#aws-appsync-monitoring)。

## 高级解析器
<a name="advanced-resolvers-js"></a>

如果您按照[设计您的架构](designing-your-schema.md#aws-appsync-designing-your-schema)中的可选分页一节进行操作，您仍然需要将解析器添加到请求才能使用分页。我们的示例使用名为 `getPosts` 的查询分页，每次仅返回一部分请求内容。该字段上的解析器代码可能如下所示：

```
/**
 * Performs a scan on the dynamodb data source
 */
export function request(ctx) {
  const { limit = 20, nextToken } = ctx.args;
  return { operation: 'Scan', limit, nextToken };
}

/**
 * @returns the result of the `put` operation
 */
export function response(ctx) {
  const { items: posts = [], nextToken } = ctx.result;
  return { posts, nextToken };
}
```

在请求中，我们传入请求的上下文。我们`limit`的 is*20*，这意味着我们在第一个查询`Posts`中最多返回 20。`nextToken` 光标固定在数据来源中的第一个 `Post` 条目。这些内容将传递给参数。然后，请求执行从第一个 `Post` 到扫描限制数的扫描。数据来源将结果存储在上下文中，该结果将传递给响应。响应返回它检索的 `Posts`，然后将 `nextToken` 设置为紧靠限制后面的 `Post` 条目。发出的下一个请求执行完全相同的操作，但从紧靠第一个查询后面的偏移开始。请记住，这些类型的请求是按顺序完成的，而不是并行完成的。