

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

# AWS AppSync 解析器参考 () JavaScript
<a name="resolver-reference-js-version"></a>

以下各节包含`APPSYNC_JS`运行时和 JavaScript 解析器参考：
+  [ JavaScript解析器概述](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)-详细了解解析器的工作原理。 AWS AppSync
+  [解析器上下文对象引用](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)：详细了解上下文对象及其在解析器中的用法。
+  [ JavaScript 解析器和函数的运行时功能](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)-详细了解支持的运行时功能以及使用实用程序来简化代码。
+  JavaScriptDynamo@@ [DB 的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html) ——详细了解解析器如何与 DynamoDB 交互。
+  [ JavaScriptresolver 函数参考 OpenSearch ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-elasticsearch-js.html) ——详细了解解析器请求和响应结构以及与 Service 的 OpenSearch 交互。
+  JavaScript Lamb@@ [da 的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html) ——详细了解解析器请求和响应结构以及与 Lambda 的交互。
+  [ JavaScript EventBridge 数据源的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-eventbridge-js.html)-了解有关解析器请求和响应结构以及与之交互的更多信息。 EventBridge
+  [ JavaScript None 数据源的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-none-js.html) ——详细了解解析器请求和响应结构以及与 NONE 数据源的交互。
+  [ JavaScript HTTP 的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-http-js.html) ——详细了解解析器请求和响应结构以及与 HTTP 端点的交互。
+  [ JavaScript Amazon RDS 的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-rds-js.html)-详细了解解析器结构以及与 RDS 的交互。
+  [ JavaScript Amazon Bedrock 的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html) ——详细了解解析器结构以及与 Amazon Bedrock 的交互。

# AWS AppSync JavaScript 解析器概述
<a name="resolver-reference-overview-js"></a>

AWS AppSync 允许您通过对数据源执行操作来响应 GraphQL 请求。对于您希望运行查询、变更或订阅的每个 GraphQL 字段，必须附加一个解析器。

解析器是 GraphQL 和数据来源之间的连接器。它们讲述 AWS AppSync 如何将传入的 GraphQL 请求转换为后端数据源的指令，以及如何将来自该数据源的响应转换回 GraphQL 响应。使用 AWS AppSync，您可以使用编写解析器 JavaScript并在 AWS AppSync (`APPSYNC_JS`) 环境中运行它们。

AWS AppSync 允许您在管道中编写由多个 AWS AppSync 函数组成的单元解析器或管道解析器。

## 支持的运行时系统功能
<a name="runtime-support-js"></a>

 AWS AppSync JavaScript 运行时提供了一部分 JavaScript 库、实用程序和功能。有关`APPSYNC_JS`运行时支持的特性和功能的完整列表，请参阅[解析器和函数的JavaScript 运行时特性](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)。

## 单位解析器
<a name="unit-resolver-js"></a>

单位解析器由定义对数据来源执行的请求和响应处理程序的代码组成。请求处理程序将上下文对象作为参数，并返回用于调用数据来源的请求负载。响应处理程序接收从数据来源返回的负载以及执行的请求结果。响应处理程序将负载转换为 GraphQL 响应以解析 GraphQL 字段。在以下示例中，解析器从 DynamoDB 数据来源中检索项目：

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
  return ddb.get({ key: { id: ctx.args.id } });
}

export const response = (ctx) => ctx.result;
```

## JavaScript 管道解析器的剖析
<a name="anatomy-of-a-pipeline-resolver-js"></a>

管道解析器由定义请求和响应处理程序以及函数列表的代码组成。每个函数具有一个对数据来源执行的**请求**和**响应**处理程序。由于管道解析器将运行委派给一组函数，因此，它不会链接到任何数据来源。单位解析器和函数是对数据来源执行操作的基元。

### 管道解析器请求处理程序
<a name="request-handler-js"></a>

管道解析器的请求处理程序（预备步骤）允许您在运行定义的函数之前执行一些准备逻辑。

### 函数列表
<a name="functions-list-js"></a>

管道解析器将按顺序运行的函数的列表。管道解析器请求处理程序评估结果作为 `ctx.prev.result` 提供给第一个函数。每个函数评估结果作为 `ctx.prev.result` 提供给下一个函数。

### 管道解析器响应处理程序
<a name="response-handler-js"></a>

管道解析器的响应处理程序允许您执行从最后一个函数的输出到预期 GraphQL 字段类型的一些最终逻辑。函数列表中的最后一个函数的输出在管道解析器响应处理程序中作为 `ctx.prev.result` 或 `ctx.result` 提供。

### 执行流程
<a name="execution-flow-js"></a>

假定一个管道解析器由两个函数组成，下面的列表表示调用解析器时的执行流程：

1.  管道解析器请求处理程序

1.  函数 1：函数请求处理程序 

1.  函数 1：数据来源调用 

1.  函数 1：函数响应处理程序 

1.  函数 2：函数请求处理程序 

1.  函数 2：数据来源调用 

1.  函数 2：函数响应处理程序 

1.  管道解析器响应处理程序 

![\[GraphQL request flow diagram showing interactions between request, data sources, and response components.\]](http://docs.aws.amazon.com/zh_cn/appsync/latest/devguide/images/appsync-js-resolver-logic.png)


### 非常有用的 `APPSYNC_JS` 运行时系统内置实用程序
<a name="useful-utilities-js"></a>

在使用管道解析器时，以下实用工具可为您提供帮助。

#### ctx.stash
<a name="ctx-stash-js"></a>

存储区是一个在每个解析器以及函数请求和响应处理程序中提供的对象。相同的存储区实例在单次解析器运行时间内有效。这意味着，您可以使用存储区在请求和响应处理程序之间以及管道解析器中的函数之间传送任意数据。你可以像普通 JavaScript 物体一样测试藏匿处。

#### ctx.prev.result
<a name="ctx-prev-result-js"></a>

`ctx.prev.result` 表示已在管道中执行的上一个操作的结果。如果上一个操作是管道解析器请求处理程序，则将 `ctx.prev.result` 提供给链中的第一个函数。如果上一个操作是第一个函数，则 `ctx.prev.result` 表示第一个函数的输出，并且可供管道中的第二个函数使用。如果上一个操作是最后一个函数，则 `ctx.prev.result` 表示最后一个函数的输出，并提供给管道解析器响应处理程序。

#### util.error
<a name="util-error-js"></a>

`util.error` 实用工具对于引发字段错误很有用。在函数请求或响应处理程序中使用 `util.error` 将立即引发字段错误，这会禁止执行后续的函数。有关更多详细信息和其他`util.error`签名，请访问[解析器和函数的JavaScript运行时功能](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)。

#### util.appendError
<a name="util-appenderror-js"></a>

`util.appendError` 与 `util.error()` 类似，主要区别在于，它不会中断处理程序评估。相反，它指示字段存在错误，但允许评估处理程序并因而返回数据。在函数中使用 `util.appendError` 将不会中断管道的执行流。有关更多详细信息和其他`util.error`签名，请访问解[析器和函数的JavaScript 运行时功能](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)。

#### runtime.earlyReturn
<a name="runtime-earlyreturn-js"></a>

`runtime.earlyReturn` 函数允许您从任何请求函数中提前返回。在解析器请求处理程序中使用 `runtime.earlyReturn` 将从解析器中返回。从 AWS AppSync 函数请求处理程序中调用它将从该函数中返回，并继续运行到管道中的下一个函数或解析器响应处理程序。

### 编写管道解析器
<a name="writing-resolvers"></a>

管道解析器还具有运行管道中的函数之前和之后的请求和响应处理程序：其请求处理程序在第一个函数的请求之前运行，其响应处理程序在最后一个函数的响应之后运行。解析器请求处理程序可以设置管道中的函数使用的数据。解析器响应处理程序负责返回映射到 GraphQL 字段输出类型的数据。在以下示例中，解析器请求处理程序定义 `allowedGroups`；返回的数据应属于这些组之一。解析器的函数可以使用该值以请求数据。解析器的响应处理程序进行最终检查并筛选结果，以确保仅返回属于允许的组的项目。

```
import { util } from '@aws-appsync/utils';

/**
 * Called before the request function of the first AppSync function in the pipeline.
 *  @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  ctx.stash.allowedGroups = ['admin'];
  ctx.stash.startedAt = util.time.nowISO8601();
  return {};
}
/**
 * Called after the response function of the last AppSync function in the pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const result = [];
  for (const item of ctx.prev.result) {
    if (ctx.stash.allowedGroups.indexOf(item.group) > -1) result.push(item);
  }
  return result;
}
```

#### 写入 AWS AppSync 函数
<a name="writing-functions"></a>

AWS AppSync 函数使您能够编写通用逻辑，这些逻辑可以在架构中的多个解析器中重复使用。例如，您可以设置一个名为的函数`QUERY_ITEMS`，该 AWS AppSync 函数负责查询来自 Amazon DynamoDB 数据源的项目。对于要用于查询项目的解析器，只需将函数添加到解析器的管道并提供要使用的查询索引即可。不必重新实施该逻辑。

## 补充主题
<a name="supplemental-topics"></a>

**主题**
+ [使用 Amazon DynamoDB 的管线解析器示例](https://docs.aws.amazon.com/appsync/latest/devguide/writing-code.html)
+ [为 `APPSYNC_JS` 运行时配置实用程序](https://docs.aws.amazon.com/appsync/latest/devguide/utility-resolvers.html)
+ [为运行时打包 TypeScript、和源映射 `APPSYNC_JS`](https://docs.aws.amazon.com/appsync/latest/devguide/additional-utilities.html)
+ [测试解析器和函数处理程序](https://docs.aws.amazon.com/appsync/latest/devguide/test-resolvers.html)
+ [从 VTL 迁移到 JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/migrating-resolvers.html)
+ [在直接数据来源访问和通过 Lambda 数据来源代理之间进行选择](https://docs.aws.amazon.com/appsync/latest/devguide/choosing-data-source.html)

# 使用 Amazon DynamoDB 的管线解析器示例
<a name="writing-code"></a>

假设您希望在名为 `getPost(id:ID!)` 的字段上附加一个管道解析器，该解析器使用以下 GraphQL 查询从 Amazon DynamoDB 数据来源中返回 `Post` 类型：

```
getPost(id:1){
    id
    title
    content
}
```

首先，使用下面的代码将一个简单的解析器附加到 `Query.getPost` 中。这是一个简单的解析器代码示例。在请求处理程序中没有定义任何逻辑，响应处理程序只是返回最后一个函数的结果。

```
/**
 * Invoked **before** the request handler of the first AppSync function in the pipeline.
 * The resolver `request` handler allows to perform some preparation logic
 * before executing the defined functions in your pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  return {}
}

/**
 * Invoked **after** the response handler of the last AppSync function in the pipeline.
 * The resolver `response` handler allows to perform some final evaluation logic
 * from the output of the last function to the expected GraphQL field type.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  return ctx.prev.result
}
```

接下来，定义从数据来源中检索 postitem 的 `GET_ITEM` 函数：

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

/**
 * Request a single item from the attached DynamoDB table datasource
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
	const { id } = ctx.args
	return ddb.get({ key: { id } })
}

/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
	const { error, result } = ctx
	if (error) {
		return util.appendError(error.message, error.type, result)
	}
	return ctx.result
}
```

如果在请求期间出现错误，则该函数的响应处理程序附加一个错误，该错误将在 GraphQL 响应中返回到调用客户端。将 `GET_ITEM` 函数添加到您的解析器函数列表中。执行查询时，`GET_ITEM`函数的请求处理程序使用的 Dynam AWS AppSync oDB 模块提供的实用程序以`DynamoDBGetItem`作为密钥创建请求。`id` `ddb.get({ key: { id } })`生成相应的`GetItem`操作：

```
{
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync 使用请求从亚马逊 DynamoDB 获取数据。在返回数据后，将由 `GET_ITEM` 函数的响应处理程序进行处理，响应处理程序检查错误，然后返回结果。

```
{
  "result" : {
    "id": 1,
    "title": "hello world",
    "content": "<long story>"
  }
}
```

最后，解析器的响应处理程序直接返回结果。

## 处理错误
<a name="working-with-errors"></a>

如果您的函数在请求期间出现错误，将在函数响应处理程序的 `ctx.error` 中提供该错误。您可以使用 `util.appendError` 实用程序将错误附加到 GraphQL 响应中。您可以使用存储区将错误提供给管道中的其他函数。请参见以下示例：

```
/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    if (!ctx.stash.errors) ctx.stash.errors = []
    ctx.stash.errors.push(ctx.error)
    return util.appendError(error.message, error.type, result);
  }
  return ctx.result;
}
```

# 为 `APPSYNC_JS` 运行时配置实用程序
<a name="utility-resolvers"></a>

AWS AppSync 提供了两个有助于使用`APPSYNC_JS`运行时开发解析器的库：
+ `@aws-appsync/eslint-plugin` - 在开发过程中快速捕获并修复问题。
+ `@aws-appsync/utils` - 在代码编辑器中提供类型验证和自动完成功能。

## 配置 ESLint 插件
<a name="utility-resolvers-configuring-eslint-plugin"></a>

[ESLint](https://eslint.org/)是一种静态分析代码以快速发现问题的工具。您可以 ESLint 作为持续集成管道的一部分运行。 `@aws-appsync/eslint-plugin`是一个 ESLint 插件，可在利用`APPSYNC_JS`运行时时时捕获代码中的无效语法。通过使用该插件，您可以在开发过程中快速获得有关代码的反馈，而无需将更改推送到云端。

`@aws-appsync/eslint-plugin` 提供了两个可以在开发过程中使用的规则集。

**"plugin:@aws-appsync/base"** 配置您可以在项目中使用的一组基本规则：


| 规则 | 说明 | 
| --- | --- | 
| no-async | 不支持异步过程和 Promise。 | 
| no-await | 不支持异步过程和 Promise。 | 
| no-classes | 不支持类。 | 
| no-for | 不支持 for（支持的 for-in 和 for-of 除外） | 
| no-continue | 不支持 continue。 | 
| no-generators | 不支持生成器。 | 
| no-yield | 不支持 yield。 | 
| no-labels | 不支持标签。 | 
| no-this | 不支持 this 关键字。 | 
| no-try | 不支持 try/catch 结构。 | 
| no-while | 不支持 while 循环。 | 
| no-disallowed-unary-operators | 不允许使用 \$1\$1、-- 和 \$1 一元运算符。 | 
| no-disallowed-binary-operators | 不允许使用 instanceof 运算符。 | 
| no-promise | 不支持异步过程和 Promise。 | 

**“插件：@aws-appsync/推荐”** 提供了一些额外的规则，但也要求你为项目添加 TypeScript 配置。


| 规则 | 说明 | 
| --- | --- | 
| no-recursion | 不允许使用递归函数调用。 | 
| no-disallowed-methods | 不允许使用某些方法。请参阅[参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)以了解支持的全套内置函数。 | 
| no-function-passing | 不允许将函数作为函数参数传递给函数。 | 
| no-function-reassign | 无法重新分配函数。 | 
| no-function-return | 函数不能是函数的返回值。 | 

要将插件添加到您的项目中，请按照 “[入门” 中的安装和使用步骤进行](https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage)操作 ESLint。然后，使用项目包管理器（例如 npm、yarn 或 pnpm）在项目中安装[插件](https://www.npmjs.com/package/@aws-appsync/eslint-plugin)：

```
$ npm install @aws-appsync/eslint-plugin
```

在 `.eslintrc.{js,yml,json}` 文件中，将 **"plugin:@aws-appsync/base"** 或 **"plugin:@aws-appsync/recommended"** 添加到 `extends` 属性中。以下代码段是以下内容的基本示例`.eslintrc`配置： JavaScript

```
{
  "extends": ["plugin:@aws-appsync/base"]
}
```

要使用 **"plugin:@aws-appsync/recommended"** 规则集，请安装所需的依赖项：

```
$ npm install -D @typescript-eslint/parser
```

然后，创建一个 `.eslintrc.js` 文件：

```
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "project": "./tsconfig.json"
  },
  "extends": ["plugin:@aws-appsync/recommended"]
}
```

# 为运行时打包 TypeScript、和源映射 `APPSYNC_JS`
<a name="additional-utilities"></a>

TypeScript 通过提供类型安全和早期错误检测来增强 AWS AppSync 开发。你可以在本地编写 TypeScript 代码，然后将其转换为， JavaScript 然后再将其与`APPSYNC_JS`运行时一起使用。该过程从为环境安装 TypeScript 和配置 tsconfig.json 开始。`APPSYNC_JS`然后，您可以使用 esbuild 等捆绑工具编译和捆绑代码。Amplify CLI 将从 GraphQL 架构生成类型，您可以在解析器代码中使用这些类型。

您可以在解析器和函数代码中使用自定义库和外部库，只要这些库符合 `APPSYNC_JS` 要求即可。捆绑工具将代码合并到单个文件中以供在中使用。 AWS AppSync可以包含源映射，以帮助调试。

## 使用库并捆绑您的代码
<a name="using-external-libraries"></a>

在您的解析器和函数代码中，您可以使用自定义库和外部库，只要它们符合 `APPSYNC_JS` 要求即可。这样，就可以在应用程序中重复使用现有的代码。要使用由多个文件定义的库，必须使用捆绑工具（例如 [esbuild](https://esbuild.github.io/)）将代码合并到一个文件中，然后将其保存到 AWS AppSync 解析器或函数中。

在捆绑代码时，请记住以下几点：
+ `APPSYNC_JS`仅支持 ECMAScript 模块 (ESM)。
+ `@aws-appsync/*` 模块集成到 `APPSYNC_JS` 中，不应将其与您的代码捆绑在一起。
+ `APPSYNC_JS` 运行时系统与 NodeJS 类似，即，不会在浏览器环境中运行代码。
+ 您可以包含可选的源映射。不过，不要包含源内容。

  要了解源映射的更多信息，请参阅[使用源映射](#source-maps)。

例如，要捆绑位于 `src/appsync/getPost.resolver.js` 中的解析器代码，您可以使用以下 esbuild CLI 命令：

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/getPost.resolver.js
```

## 构建您的代码并使用 TypeScript
<a name="working-with-typescript"></a>

[TypeScript](https://www.typescriptlang.org/)是一种由 Microsoft 开发 JavaScript的编程语言，它提供所有功能以及 TypeScript 打字系统。在将代码保存 TypeScript 到之前，您可以使用编写类型安全的代码并在构建时捕获错误和错误。 AWS AppSync`@aws-appsync/utils` 包是完全类型化的。

`APPSYNC_JS`运行时不 TypeScript 直接支持。在将 TypeScript 代码保存到之前，必须先将 JavaScript 代码转换为`APPSYNC_JS`运行时支持的代码。 AWS AppSync您可以使用 TypeScript 在本地集成开发环境 (IDE) 中编写代码，但请注意，您无法在 AWS AppSync 控制台中创建 TypeScript 代码。

首先，请确保已在项目中[TypeScript](https://www.typescriptlang.org/download)安装。然后，使用配置您的 TypeScript 转码设置以与`APPSYNC_JS`运行时配合使用[TSConfig](https://www.typescriptlang.org/tsconfig)。以下是您可以使用的基本 `tsconfig.json` 文件示例：

```
// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
   "noEmit": true,
   "moduleResolution": "node",
  }
}
```

然后，您可以使用 esbuild 等捆绑工具编译和捆绑代码。例如，给定一个项目，你的 AWS AppSync 代码位于`src/appsync`，你可以使用以下命令来编译和捆绑你的代码：

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/**/*.ts
```

### 使用 Amplify codegen
<a name="working-with-amplify-codegen"></a>

您可以使用 [Amplify CLI](https://docs.amplify.aws/cli/) 生成架构的类型。从 `schema.graphql` 文件所在的目录中，运行以下命令并查看提示以配置 codegen：

```
$  npx @aws-amplify/cli codegen add
```

要在某些情况下（例如，更新架构时）重新生成 codegen，请运行以下命令：

```
$ npx @aws-amplify/cli codegen
```

然后，您可以在解析器代码中使用生成的类型。例如，给定以下架构：

```
type Todo {
  id: ID!
  title: String!
  description: String
}

type Mutation {
  createTodo(title: String!, description: String): Todo
}

type Query {
  listTodos: Todo
}
```

你可以在以下示例 AWS AppSync 函数中使用生成的类型：

```
import { Context, util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'
import { CreateTodoMutationVariables, Todo } from './API' // codegen

export function request(ctx: Context<CreateTodoMutationVariables>) {
	ctx.args.description = ctx.args.description ?? 'created on ' + util.time.nowISO8601()
	return ddb.put<Todo>({ key: { id: util.autoId() }, item: ctx.args })
}

export function response(ctx) {
	return ctx.result as Todo
}
```

### 在中使用泛型 TypeScript
<a name="working-with-typescript-generics"></a>

您可以将泛型与提供的多种类型一起使用。例如，下面的代码片段是 `Todo` 类型：

```
export type Todo = {
  __typename: "Todo",
  id: string,
  title: string,
  description?: string | null,
};
```

您可以为使用 `Todo` 的订阅编写解析器。在您的 IDE 中，类型定义和自动完成提示将指导您正确使用 `toSubscriptionFilter` 转换实用程序：

```
import { util, Context, extensions } from '@aws-appsync/utils'
import { Todo } from './API'

export function request(ctx: Context) {
  return {}
}

export function response(ctx: Context) {
  const filter = util.transform.toSubscriptionFilter<Todo>({
    title: { beginsWith: 'hello' },
    description: { contains: 'created' },
  })
  extensions.setSubscriptionFilter(filter)
  return null
}
```

## 检查您的包
<a name="using-lint-with-bundles"></a>

您可以导入 `esbuild-plugin-eslint` 插件以自动检查您的包。然后，您可以提供启用 ESLint 功能的 `plugins` 值以启用该插件。以下是在名为的文件中使用 esbuild JavaScript API 的片段：`build.mjs`

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

## 使用源映射
<a name="source-maps"></a>

您可以在 JavaScript 代码中提供内联源映射 (`sourcemap`)。当您打包 JavaScript 或 TypeScript 编写代码并希望在日志和运行时 JavaScript 错误消息中查看对输入源文件的引用时，源映射非常有用。

您的 `sourcemap` 必须出现在代码末尾。它是由采用以下格式的单个注释行定义的：

```
//# sourceMappingURL=data:application/json;base64,<base64 encoded string>
```

示例如下：

```
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliLmpzIiwgImNvZGUuanMiXSwKICAibWFwcGluZ3MiOiAiO0FBQU8sU0FBUyxRQUFRO0FBQ3RCLFNBQU87QUFDVDs7O0FDRE8sU0FBUyxRQUFRLEtBQUs7QUFDM0IsU0FBTyxNQUFNO0FBQ2Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
```

可以使用 esbuild 创建源映射。以下示例向您展示了在构建和捆绑代码时如何使用 esbuild JavaScript API 来包含内联源映射：

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  sourcemap: 'inline',
  sourcesContent: false,
  
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

特别是，`sourcemap` 和 `sourcesContent` 选项指定应在每个构建末尾的行中添加源映射，但源映射不应包含源内容。作为惯例，我们建议不要在您的 `sourcemap` 中包含源内容。您可以将 `sources-content` 设置为 `false` 以在 esbuild 中禁用该功能。

要说明源映射的工作方式，请查看以下示例，其中解析器代码引用帮助程序库中的帮助程序函数。该代码在解析器代码和帮助程序库中包含日志语句：

**./src/default.resolver.ts**（您的解析器）

```
import { Context } from '@aws-appsync/utils'
import { hello, logit } from './helper'

export function request(ctx: Context) {
  console.log('start >')
  logit('hello world', 42, true)
  console.log('< end')
  return 'test'
}

export function response(ctx: Context): boolean {
  hello()
  return ctx.prev.result
}
```

**.src/helper.ts**（帮助程序文件）

```
export const logit = (...rest: any[]) => {
  // a special logger
  console.log('[logger]', ...rest.map((r) => `<${r}>`))
}

export const hello = () => {
  // This just returns a simple sentence, but it could do more.
  console.log('i just say hello..')
}
```

在您构建并捆绑解析器文件时，您的解析器代码将包含内联源映射。当您的解析器运行时， CloudWatch 日志中会显示以下条目：

![\[CloudWatch log entries showing resolver code execution with inline source map information.\]](http://docs.aws.amazon.com/zh_cn/appsync/latest/devguide/images/cloudwatch-sourcemap.jpeg)


查看 CloudWatch 日志中的条目，您会注意到这两个文件的功能已捆绑在一起并行运行。每个文件的原始文件名也清晰地反映在日志中。

# 在中测试你的解析器和函数处理器 AWS AppSync
<a name="test-resolvers"></a>

在将代码保存到解析器或函数之前，您可以通过 `EvaluateCode` API 命令使用模拟数据远程测试解析器和函数处理程序。要开始使用该命令，请确保您已将 `appsync:evaluatecode` 权限添加到您的策略中。例如：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateCode",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

您可以使用 [AWS CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/index.html) 或来利用该命令[AWS SDKs](https://aws.amazon.com/tools/)。例如，要使用 CLI 测试代码，只需指向您的文件，提供上下文并指定要评估的处理程序：

```
aws appsync evaluate-code \
  --code file://code.js \
  --function request \
  --context file://context.json \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0
```

响应包含一个 `evaluationResult`，其中包含处理程序返回的负载。它还包含一个 `logs` 对象，其中保存处理程序在评估期间生成的日志列表。这样，就可以轻松调试代码执行，并查看有关评估的信息以帮助排除故障。例如：

```
{
    "evaluationResult": "{\"operation\":\"PutItem\",\"key\":{\"id\":{\"S\":\"record-id\"}},\"attributeValues\":{\"owner\":{\"S\":\"John doe\"},\"expectedVersion\":{\"N\":2},\"authorId\":{\"S\":\"Sammy Davis\"}}}",
    "logs": [
        "INFO - code.js:5:3: \"current id\" \"record-id\"",
        "INFO - code.js:9:3: \"request evaluated\""
    ]
}
```

可以将评估结果解析为 JSON，其中提供：

```
{
  "operation": "PutItem",
  "key": {
    "id": {
      "S": "record-id"
    }
  },
  "attributeValues": {
    "owner": {
      "S": "John doe"
    },
    "expectedVersion": {
      "N": 2
    },
    "authorId": {
      "S": "Sammy Davis"
    }
  }
}
```

通过使用 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' })
const runtime = {name:'APPSYNC_JS',runtimeVersion:'1.0.0')

test('request correctly calls DynamoDB', async () => {
  const code = fs.readFileSync('./code.js', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateCode({ code, context, runtime, function: 'request' }).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 totalTime: 1.511 s, estimated 2 s
```

# 从 VTL 迁移到 in JavaScript AWS AppSync
<a name="migrating-resolvers"></a>

AWS AppSync 允许您使用 VTL 或为解析器和函数编写业务逻辑。 JavaScript使用这两种语言，您都可以编写逻辑来指导 AWS AppSync 服务如何与您的数据源进行交互。在使用 VTL 时，您可以编写评估结果必须为有效 JSON 编码字符串的映射模板。使用 JavaScript，您可以编写返回对象的请求和响应处理程序。您不会返回 JSON 编码的字符串。

例如，采用以下 VTL 映射模板以获取 Amazon DynamoDB 项目：

```
{
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}
```

`$util.dynamodb.toDynamoDBJson` 实用程序返回 JSON 编码的字符串。如果 `$ctx.args.id` 设置为 `<id>`，则模板评估结果为有效的 JSON 编码字符串：

```
{
    "operation": "GetItem",
    "key": {
        "id": {"S": "<id>"},
    }
}
```

使用时 JavaScript，您无需在代码中打印出未经处理的 JSON 编码字符串，`toDynamoDBJson`也不需要使用类似的实用程序。上述映射模板的等效示例是：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: {id: util.dynamodb.toDynamoDB(ctx.args.id)}
  };
}
```

另一种方法是使用 `util.dynamodb.toMapValues`，这是处理值对象的建议方法：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

它的评估结果为：

```
{
  "operation": "GetItem",
  "key": {
    "id": {
      "S": "<id>"
    }
  }
}
```

**注意**  
我们建议将 DynamoDB 模块与 DynamoDB 数据来源一起使用：  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	ddb.get({ key: { id: ctx.args.id } })
}
```

再举一个例子，采用以下映射模板将项目放入 Amazon DynamoDB 数据来源中：

```
{
    "operation" : "PutItem",
    "key" : {
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

在评估后，该映射模板字符串必须生成有效的 JSON 编码字符串。使用时 JavaScript，您的代码会直接返回请求对象：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id = util.autoId(), ...values } = ctx.args;
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id }),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

它的评估结果为：

```
{
  "operation": "PutItem",
  "key": {
    "id": { "S": "2bff3f05-ff8c-4ed8-92b4-767e29fc4e63" }
  },
  "attributeValues": {
    "firstname": { "S": "Shaggy" },
    "age": { "N": 4 }
  }
}
```

**注意**  
我们建议将 DynamoDB 模块与 DynamoDB 数据来源一起使用：  

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	const { id = util.autoId(), ...item } = ctx.args
	return ddb.put({ key: { id }, item })
}
```

# 在直接数据来源访问和通过 Lambda 数据来源代理之间进行选择
<a name="choosing-data-source"></a>

借 AWS AppSync 助 and `APPSYNC_JS` the runtime，您可以编写自己的代码，通过使用 AWS AppSync 函数访问您的数据源来实现您的自定义业务逻辑。这使您可以轻松地直接与 Amazon DynamoDB、Aurora OpenSearch Serverless、服务 APIs、HTTP 和其他服务等数据源进行交互， AWS 而无需部署额外的计算服务或基础设施。 AWS AppSync 还可以通过配置 Lambda 数据源轻松地与 AWS Lambda 函数进行交互。Lambda 数据源允许您使用全套功能运行复杂 AWS Lambda的业务逻辑来解析 GraphQL 请求。在大多数情况下，直接连接到其目标数据源的 AWS AppSync 函数将提供您需要的所有功能。在您需要实施 `APPSYNC_JS` 运行时系统不支持的复杂业务逻辑时，您可以将 Lambda 数据来源作为代理以与目标数据来源进行交互。


|  |  |  | 
| --- |--- |--- |
|  | 直接数据源集成 | 作为代理的 Lambda 数据源 | 
| 使用案例 | AWS AppSync 函数直接与 API 数据源交互。 | AWS AppSync 函数调用与 API 数据源交互的 Lambda。 | 
| 运行时 | APPSYNC\$1JS (JavaScript) | 任何支持的 Lambda 运行时 | 
| 代码的最大大小 | 每个函数 32,000 个 AWS AppSync字符 | 每个 Lambda 50 MB（已压缩，用于直接上传） | 
| 外部模块 | 有限——仅支持 APPSYNC\$1JS 的功能 | 是 | 
| 拨打任何 AWS 服务电话 | 是-使用 AWS AppSync HTTP 数据源 | 是-使用 AWS SDK | 
| 访问请求标头 | 是 | 是 | 
| 网络访问 | 否 | 是 | 
| 文件系统访问 | 否 | 是 | 
| 日志和指标 | 是 | 是 | 
| 完全在内部构建和测试 AppSync | 是 | 否 | 
| 冷启动 | 否 | 否-使用预配置的并发性 | 
| 自动扩缩 | 是的——透明地 AWS AppSync | 是-按照 Lambda 中的配置 | 
| 定价 | 不收取额外费用 | 针对 Lambda 使用量收费 | 

AWS AppSync 直接与其目标数据源集成的函数非常适合以下用例：
+  与亚马逊 DynamoDB、Aurora Serverless 和服务互动 OpenSearch 
+  与 HTTP 交互 APIs 并传递传入的标头 
+  使用 HTTP 数据源与 AWS 服务交互（使用提供的数据源角色 AWS AppSync 自动签署请求） 
+  在访问数据来源之前实施访问控制 
+  在完成请求之前对检索的数据实施筛选 
+  通过在解析器管道中按顺序执行 AWS AppSync 函数来实现简单的编排 
+  控制查询和变更中的缓存和订阅连接。

AWS AppSync 使用 Lambda 数据源作为代理的函数非常适合以下用例：
+  使用 Velocity 模板语言 (VTL) 以外的 JavaScript 语言 
+  调整和控制 CPU 或内存以优化性能 
+  导入第三方库或要求使用 `APPSYNC_JS` 中不支持的功能 
+  发出多个网络请求以 and/or 获取文件系统访问权限以完成查询 
+  使用[批处理配置](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html)对请求进行批处理。

# AWS AppSync JavaScript 解析器上下文对象引用
<a name="resolver-context-reference-js"></a>

AWS AppSync 定义了一组用于处理请求和响应处理程序的变量和函数。这样，就可以更轻松地通过 GraphQL 对数据进行逻辑操作。本文档介绍了这些函数并提供了示例。

## 使用 `context`
<a name="accessing-the-context-js"></a>

请求和响应处理程序的 `context` 参数是一个对象，它保存解析器调用的所有上下文信息。它具有以下结构：

```
type Context = {
  arguments: any;
  args: any;
  identity: Identity;
  source: any;
  error?: {
    message: string;
    type: string;
  };
  stash: any;
  result: any;
  prev: any;
  request: Request;
  info: Info;
};
```

**注意**  
您经常会发现 `context` 对象是作为 `ctx` 引用的。

`context` 对象中的每个字段定义如下：

### `context` 字段
<a name="accessing-the-context-list-js"></a>

** `arguments` **  
包含该字段的所有 GraphQL 参数的映射。

** `identity` **  
包含有关调用方的信息的对象。有关该字段结构的更多信息，请参阅[身份](#aws-appsync-resolver-context-reference-identity-js)。

** `source` **  
包含父字段解析的映射。

** `stash` **  
存储区是一个在每个解析器以及函数处理程序中提供的对象。相同的存储区对象在单次解析器运行时间内有效。这意味着，您可以使用存储区在请求和响应处理程序之间以及管道解析器中的函数之间传送任意数据。  
您无法删除或替换整个存储区，但可以添加、更新、删除和读取存储区属性。
您可以修改以下代码示例之一，以将项目添加到存储区中：  

```
//Example 1
ctx.stash.newItem = { key: "something" }

//Example 2
Object.assign(ctx.stash, {key1: value1, key2: value})
```
您可以修改以下代码，以从存储区中删除项目：  

```
delete ctx.stash.key
```

** `result` **  
此解析器结果的容器。该字段仅适用于响应处理程序。  
例如，如果要解析以下查询的 `author` 字段：  

```
query {
    getPost(id: 1234) {
        postId
        title
        content
        author {
            id
            name
        }
    }
}
```
然后，在评估响应处理程序时，可以使用完整的 `context` 变量：  

```
{
  "arguments" : {
    id: "1234"
  },
  "source": {},
  "result" : {
      "postId": "1234",
      "title": "Some title",
      "content": "Some content",
      "author": {
        "id": "5678",
        "name": "Author Name"
      }
  },
  "identity" : {
      "sourceIp" : ["x.x.x.x"],
      "userArn" : "arn:aws:iam::123456789012:user/appsync",
      "accountId" : "666666666666",
      "user" : "AIDAAAAAAAAAAAAAAAAAA"
  }
}
```

** `prev.result` **  
在管道解析器中执行的任何以前操作的结果。  
如果上一个操作是管道解析器的请求处理程序，则 `ctx.prev.result` 表示该评估结果，并提供给管道中的第一个函数。  
如果上一个操作是第一个函数，则 `ctx.prev.result` 表示第一个函数响应处理程序的评估结果，并提供给管道中的第二个函数。  
如果上一个操作是最后一个函数，则 `ctx.prev.result` 表示最后一个函数的评估结果，并提供给管道解析器的响应处理程序。

** `info` **  
包含有关 GraphQL 请求的信息的对象。有关该字段的结构，请参阅[信息](#aws-appsync-resolver-context-reference-info-js)。

### 身份
<a name="aws-appsync-resolver-context-reference-identity-js"></a>

`identity` 部分包含调用方的相关信息。此部分的形式取决于您的 AWS AppSync API 的授权类型。

有关 AWS AppSync 安全选项的更多信息，请参阅[授权和身份验证](security-authz.md#aws-appsync-security)。

** `API_KEY` 授权**  
不填充 `identity` 字段。

**`AWS_LAMBDA` 授权**  
`identity` 采用以下格式：  

```
type AppSyncIdentityLambda = {
  resolverContext: any;
};
```
`identity` 包含 `resolverContext` 密钥，其中包含为请求授权的 Lambda 函数返回的相同 `resolverContext` 内容。

** `AWS_IAM` 授权**  
`identity` 采用以下格式：  

```
type AppSyncIdentityIAM = {
  accountId: string;
  cognitoIdentityPoolId: string;
  cognitoIdentityId: string;
  sourceIp: string[];
  username: string;
  userArn: string;
  cognitoIdentityAuthType: string;
  cognitoIdentityAuthProvider: string;
};
```

** `AMAZON_COGNITO_USER_POOLS` 授权**  
`identity` 采用以下格式：  

```
type AppSyncIdentityCognito = {
  sourceIp: string[];
  username: string;
  groups: string[] | null;
  sub: string;
  issuer: string;
  claims: any;
  defaultAuthStrategy: string;
};
```

每个字段的定义如下所示：

** `accountId` **  
来电者的 AWS 账户 ID。

** `claims` **  
用户拥有的声明。

** `cognitoIdentityAuthType` **  
根据身份类型确定经过身份验证或未经身份验证。

** `cognitoIdentityAuthProvider` **  
外部身份提供程序信息的逗号分隔列表，用于获取对请求进行签名时使用的凭证。

** `cognitoIdentityId` **  
调用方的 Amazon Cognito 身份 ID。

** `cognitoIdentityPoolId` **  
与调用方关联的 Amazon Cognito 身份池 ID。

** `defaultAuthStrategy` **  
此调用方的默认授权策略（`ALLOW` 或 `DENY`）。

** `issuer` **  
令牌发布者。

** `sourceIp` **  
 AWS AppSync 接听的来电者的源 IP 地址。如果请求不包含 `x-forwarded-for` 标头，则源 IP 值仅包含来自 TCP 连接的单个 IP 地址。如果请求中包含 `x-forwarded-for` 标头，那么源 IP 将是来自 `x-forwarded-for` 标头的 IP 地址列表，以及来自 TCP 连接的 IP 地址。

** `sub` **  
经过验证的用户的 UUID。

** `user` **  
IAM 用户。

** `userArn` **  
IAM 用户的 Amazon 资源名称 (ARN)。

** `username` **  
已验证的用户的用户名。对于 `AMAZON_COGNITO_USER_POOLS` 授权，*用户名*的值是 *cognito:username* 属性的值。在`AWS_IAM`授权的情况下，用户名的值就是* AWS 用户*委托人的值。如果您将 IAM 授权与从 Amazon Cognito 身份池提供的凭证一起使用，我们建议您使用 `cognitoIdentityId`。

### 访问请求标头
<a name="aws-appsync-resolver-context-reference-util-js"></a>

AWS AppSync 支持从客户端传递自定义标头并使用在 GraphQL 解析器中访问它们。`ctx.request.headers`然后，您可以使用标头值执行操作，例如，将数据插入到数据来源或进行授权检查。您可以在命令行中使用 `$curl` 将一个或多个请求标头与 API 密钥一起使用，如以下示例中所示：

**单标头示例** 

假设您设置一个 `custom` 标头，值为 `nadia`，如下所示：

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

然后可使用 `ctx.request.headers.custom` 访问它。例如，对于 DynamoDB，它可能位于以下代码中：

```
"custom": util.dynamodb.toDynamoDB(ctx.request.headers.custom)
```

**多标头示例** 

您也可以在单个请求中传递多个标头，并在解析器处理程序中访问这些标头。例如，如果为 `custom` 标头设置了两个值：

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:bailey" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

它们可以作为一个数组访问，例如 `ctx.request.headers.custom[1]`。

**注意**  
AWS AppSync 不会在中公开 cookie 标头`ctx.request.headers`。

### 访问请求自定义域名
<a name="aws-access-requested-custom-domain-names-js"></a>

AWS AppSync 支持配置自定义域，您可以使用该域名访问您的 GraphQL 和实时终端节点。 APIs在使用自定义域名发出请求时，您可以使用 `ctx.request.domainName` 获取域名。

在使用默认 GraphQL 终端节点域名时，值为 `null`。

### 信息
<a name="aws-appsync-resolver-context-reference-info-js"></a>

`info` 部分包含有关 GraphQL 请求的信息。该部分采用以下格式：

```
type Info = {
  fieldName: string;
  parentTypeName: string;
  variables: any;
  selectionSetList: string[];
  selectionSetGraphQL: string;
};
```

每个字段的定义如下所示：

** `fieldName` **  
当前正在解析的字段的名称。

** `parentTypeName` **  
当前正在解析的字段的父类型的名称。

** `variables` **  
保留传递到 GraphQL 请求的所有变量的映射。

** `selectionSetList` **  
GraphQL 选择集中字段的列表表示形式。具有别名的字段仅按别名进行引用，而不按字段名称进行引用。以下示例对此详细进行了介绍。

** `selectionSetGraphQL` **  
选择集的字符串表示形式，格式为 GraphQL 架构定义语言 (SDL)。尽管片段不会合并到选择集中，但会保留内联片段，如以下示例中所示。

**注意**  
`JSON.stringify` 不会在字符串序列化中包含 `selectionSetGraphQL` 和 `selectionSetList`。您必须直接引用这些属性。

例如，如果您要解析以下查询的 `getPost` 字段：

```
query {
  getPost(id: $postId) {
    postId
    title
    secondTitle: title
    content
    author(id: $authorId) {
      authorId
      name
    }
    secondAuthor(id: "789") {
      authorId
    }
    ... on Post {
      inlineFrag: comments: {
        id
      }
    }
    ... postFrag
  }
}

fragment postFrag on Post {
  postFrag: comments: {
    id
  }
}
```

在处理处理程序时可使用的完整 `ctx.info` 变量可能是：

```
{
  "fieldName": "getPost",
  "parentTypeName": "Query",
  "variables": {
    "postId": "123",
    "authorId": "456"
  },
  "selectionSetList": [
    "postId",
    "title",
    "secondTitle"
    "content",
    "author",
    "author/authorId",
    "author/name",
    "secondAuthor",
    "secondAuthor/authorId",
    "inlineFragComments",
    "inlineFragComments/id",
    "postFragComments",
    "postFragComments/id"
  ],
  "selectionSetGraphQL": "{\n  getPost(id: $postId) {\n    postId\n    title\n    secondTitle: title\n    content\n    author(id: $authorId) {\n      authorId\n      name\n    }\n    secondAuthor(id: \"789\") {\n      authorId\n    }\n    ... on Post {\n      inlineFrag: comments {\n        id\n      }\n    }\n    ... postFrag\n  }\n}"
}
```

`selectionSetList` 仅公开属于当前类型的字段。如果当前类型是接口或联合，则仅公开属于该接口的选定字段。例如，给定以下架构：

```
type Query {
    node(id: ID!): Node
}

interface Node {
    id: ID
}

type Post implements Node {
    id: ID
    title: String
    author: String
}

type Blog implements Node {
    id: ID
    title: String
    category: String
}
```

以及以下查询：

```
query {
    node(id: "post1") {
        id
        ... on Post {
            title
        }

        ... on Blog {
            title
        }
    }
}
```

如果在进行 `Query.node` 字段解析时调用 `ctx.info.selectionSetList`，则仅公开 `id`：

```
"selectionSetList": [
    "id"
]
```

# AWS AppSync JavaScript 解析器和函数的运行时功能
<a name="resolver-util-reference-js"></a>

`APPSYNC_JS`运行时环境提供的功能与 [ECMAScript (ES) 版本 6.0](https://262.ecma-international.org/6.0/) 类似。它支持该版本的一部分功能，并提供一些不属于 ES 规范的额外方法（实用程序）。以下主题列出了所有支持的语言特征：
+  [支持的运行时特征](https://docs.aws.amazon.com/appsync/latest/devguide/supported-features.html)：详细了解支持的核心特征、基元对象、内置对象和函数等。
+  [内置实用程序](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html)：util 变量包含帮助您处理数据的常规实用程序方法。除非另行指定，否则所有实用程序均使用 UTF-8 字符集。
+  [内置模块](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html)-详细了解内置模块如何帮助编写 JavaScript 解析器和函数。
+  [运行时实用程序](https://docs.aws.amazon.com/appsync/latest/devguide/runtime-utils-js.html)：运行时库提供一些实用程序以控制或修改解析器和函数的运行时属性。
+  [util.time 中的时间帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/time-helpers-in-util-time-js.html)：util.time 变量包含的日期时间方法有助于生成时间截，在不同的日期时间格式之间进行转换，并解析日期时间字符串。日期时间格式的语法基于该语法 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)，您可以参考该语法以获取更多文档。
+  [util.dynamodb 中的 DynamoDB 帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html)：util.dynamodb 包含一些帮助程序方法，可以更轻松地在 Amazon DynamoDB 中写入和读取数据，例如自动类型映射和格式设置。
+  [util.http 中的 HTTP 帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/http-helpers-in-utils-http-js.html)：util.http 实用程序提供一些帮助程序方法，可用于管理 HTTP 请求参数和添加响应标头。
+  [util.transform 中的转换帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/transformation-helpers-in-utils-transform-js.html)：util.transform 包含一些帮助程序方法，可以更轻松地对数据来源执行复杂的操作。
+  [util.str 中的字符串帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/str-helpers-in-util-str-js.html)：util.str 包含一些帮助执行常见字符串操作的方法。
+  [扩展程序](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)：extensions 包含一组在解析器中执行额外操作的方法。
+  [util.xml 中的 XML 帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/xml-helpers-in-util-xml-js.html)：util.xml 包含一些帮助进行 XML 字符串转换的方法。

**注意**  
目前，该参考仅适用于运行时系统版本 **1.0.0**。

# 支持的运行时系统功能
<a name="supported-features"></a>

以下几节介绍了支持的 APPSYNC\$1JS 运行时系统功能集。

## 核心功能
<a name="core-features"></a>

支持以下核心功能。

------
#### [ Types ]

支持以下类型：
+ 数字
+ 字符串
+ 布尔值
+ 对象
+ 数组
+ 函数

------
#### [ Operators ]

支持的运算符，其中包括：
+ 标准数学运算符（`+`、`-`、`/`、`%`、`*` 等）
+ Null 合并运算符 (`??`)
+ 可选链 (`?.`)
+ 按位运算符
+ `void` 和 `typeof` 运算符
+ 展开运算符（`...`）

不支持以下运算符：
+ 一元运算符（`++`、`--` 和 `~`）
+ `in` 运算符
**注意**  
可以使用 `Object.hasOwn` 运算符检查指定的属性是否位于指定的对象中。

------
#### [ Statements ]

支持以下语句：
+ `const`
+ `let`
+ `var`
+ `break`
+ `else`
+ `for-in`
+ `for-of` 
+ `if`
+ `return`
+ `switch`
+ spread syntax

不支持以下语句：
+ `catch`
+ `continue`
+ `do-while`
+ `finally`
+ `for(initialization; condition; afterthought)`
**注意**  
例外情况是 `for-in` 和 `for-of` 表达式，支持这些表达式。
+ `throw`
+ `try`
+ `while`
+ 带标签的语句

------
#### [ Literals ]

支持以下 ES 6 [模板文本](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)：
+ 多行字符串
+ 表达式插值
+ 嵌套模板

------
#### [ Functions ]

支持以下函数语法：
+ 支持函数声明。
+ 支持 ES 6 箭头函数。
+ 支持 ES 6 剩余参数语法。

------
#### [ Strict mode ]

默认情况下，函数在严格模式下运行，因此您无需在函数代码中添加 `use_strict` 语句。无法对其进行更改。

------

## 原语对象
<a name="primitive-objects"></a>

支持以下 ES 基元对象及其函数。

------
#### [ Object ]

支持以下对象：
+ `Object.assign()`
+ `Object.entries()` 
+ `Object.hasOwn()`
+ `Object.keys()` 
+ `Object.values()`
+ `delete` 

------
#### [ String ]

支持以下字符串：
+  `String.prototype.length()` 
+  `String.prototype.charAt()` 
+  `String.prototype.concat()` 
+  `String.prototype.endsWith()` 
+  `String.prototype.indexOf()` 
+  `String.prototype.lastIndexOf()` 
+  `String.raw()` 
+  `String.prototype.replace()`
**注意**  
不支持正则表达式。  
但是，提供的参数支持 Java 正则表达式结构。有关更多信息，请参阅[模式](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)。
+ `String.prototype.replaceAll()`
**注意**  
不支持正则表达式。  
但是，提供的参数支持 Java 正则表达式结构。有关更多信息，请参阅[模式](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)。
+  `String.prototype.slice()` 
+  `String.prototype.split()` 
+  `String.prototype.startsWith()` 
+  `String.prototype.toLowerCase()` 
+  `String.prototype.toUpperCase()` 
+  `String.prototype.trim()` 
+  `String.prototype.trimEnd()` 
+  `String.prototype.trimStart()` 

------
#### [ Number ]

支持以下数字：
+  `Number.isFinite` 
+  `Number.isNaN` 

------

## 内置对象和函数
<a name="built-in-objects-functions"></a>

支持以下函数和对象。

------
#### [ Math ]

支持以下数学函数：
+  `Math.random()` 
+  `Math.min()` 
+  `Math.max()` 
+  `Math.round()` 
+  `Math.floor()` 
+  `Math.ceil()` 

------
#### [ Array ]

支持以下数组方法：
+ `Array.prototype.length` 
+ `Array.prototype.concat()` 
+ `Array.prototype.fill()` 
+ `Array.prototype.flat()` 
+ `Array.prototype.indexOf()` 
+ `Array.prototype.join()` 
+ `Array.prototype.lastIndexOf()` 
+ `Array.prototype.pop()` 
+ `Array.prototype.push()` 
+ `Array.prototype.reverse()` 
+ `Array.prototype.shift()` 
+ `Array.prototype.slice()` 
+ `Array.prototype.sort()`
**注意**  
`Array.prototype.sort()` 不支持参数。
+ `Array.prototype.splice()` 
+ `Array.prototype.unshift()`
+ `Array.prototype.forEach()`
+ `Array.prototype.map()`
+ `Array.prototype.flatMap()`
+ `Array.prototype.filter()`
+ `Array.prototype.reduce()`
+ `Array.prototype.reduceRight()`
+ `Array.prototype.find()`
+ `Array.prototype.some()`
+ `Array.prototype.every()`
+ `Array.prototype.findIndex()`
+ `Array.prototype.findLast()`
+ `Array.prototype.findLastIndex()`
+ `delete` 

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

可以使用控制台对象进行调试。在实时查询执行期间，控制台 log/error 语句会发送到 Amazon CloudWatch Logs（如果启用了日志记录）。在使用 `evaluateCode` 评估代码期间，将在命令响应中返回日志语句。
+ `console.error()`
+ `console.log()`

------
#### [ Function ]
+ 不支持 `apply`、`bind` 和 `call` 方法。
+ 不支持函数构造函数。
+ 不支持将函数作为参数传递。
+ 不支持递归函数调用。

------
#### [ JSON ]

支持以下 JSON 方法：
+ `JSON.parse()`
**注意**  
如果解析的字符串不是有效的 JSON，则返回空字符串。
+ `JSON.stringify()`

------
#### [ Promises ]

不支持异步过程，也不支持 Promise。

**注意**  
中不支持在`APPSYNC_JS`运行时内访问网络和文件系统 AWS AppSync。 AWS AppSync 根据 AWS AppSync 解析器或 AWS AppSync 函数发出的请求处理所有 I/O 操作。

------

## 全局变量
<a name="globals"></a>

支持以下全局常数：
+  `NaN` 
+  `Infinity` 
+  `undefined`
+ [https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html)
+ [https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)
+ `runtime`

## 错误类型
<a name="error-types"></a>

不支持使用 `throw` 引发错误。您可以使用 `util.error()` 函数返回错误。您可以使用 `util.appendError` 函数在 GraphQL 响应中包含错误。

有关更多信息，请参阅[错误实用程序](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html#utility-helpers-in-error-js)。

# 内置实用程序
<a name="built-in-util-js"></a>

`util` 变量包含帮助您处理数据的常规实用程序方法。除非另行指定，否则所有实用程序均使用 UTF-8 字符集。

## 编码实用程序
<a name="utility-helpers-in-encoding"></a>

### 编码实用程序列表
<a name="utility-helpers-in-encoding-list-js"></a>

 **`util.urlEncode(String)`**  
将输入字符串作为 `application/x-www-form-urlencoded` 编码字符串返回。

 **`util.urlDecode(String)`**  
将 `application/x-www-form-urlencoded` 编码的字符串解码回未编码的形式。

**`util.base64Encode(string) : string`**  
将输入编码为 base64 编码字符串。

**`util.base64Decode(string) : string`**  
对 base64 编码字符串中的数据进行解码。

## ID 生成实用程序
<a name="utility-helpers-in-id-gen-js"></a>

### ID 生成实用程序列表
<a name="utility-helpers-in-id-gen-list-js"></a>

 **`util.autoId()`**  
返回 128 位随机生成的 UUID。

**`util.autoUlid()`**  
返回一个 128 位随机生成的 ULID（可按字典排序的通用唯一标识符）。

**`util.autoKsuid()`**  
返回一个 128 位随机生成的 KSUID（K 可排序唯一标识符），它使用 Base62 编码为长度为 27 的字符串。

## 错误实用程序
<a name="utility-helpers-in-error-js"></a>

### 错误实用程序列表
<a name="utility-helpers-in-error-list-js"></a>

 **`util.error(String, String?, Object?, Object?)`**  
引发自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。此外，还可以指定 `errorType`、`data` 和 `errorInfo` 字段。将在 GraphQL 响应中 `data` 内部对应的 `error` 块中添加 `errors` 值。  
`data` 将根据查询选择集进行筛选。将在 GraphQL 响应中 `errorInfo` 内部对应的 `error` 块中添加 `errors` 值。  
`errorInfo` **不会**根据查询选择集进行筛选。

 **`util.appendError(String, String?, Object?, Object?)`**  
追加自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。此外，还可以指定 `errorType`、`data` 和 `errorInfo` 字段。与 `util.error(String, String?, Object?, Object?)` 不同，不会中断模板评估，因此，可以向调用方返回数据。将在 GraphQL 响应中 `data` 内部对应的 `error` 块中添加 `errors` 值。  
`data` 将根据查询选择集进行筛选。将在 GraphQL 响应中 `errorInfo` 内部对应的 `error` 块中添加 `errors` 值。  
`errorInfo` **不会**根据查询选择集进行筛选。

## 类型和模式匹配实用程序
<a name="utility-helpers-in-patterns-js"></a>

### 类型和模式匹配实用程序列表
<a name="utility-helpers-in-patterns-js-list"></a>

**`util.matches(String, String) : Boolean`**  
如果在第一个参数中指定的模式与第二个参数中提供的数据匹配，则返回 true。模式必须为正则表达式，例如 `util.matches("a*b", "aaaaab")`。此功能以[模式](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)为基础，您可参考其他文档，进一步了解此内容。

 **`util.authType()`**   
返回描述请求使用的多重身份验证类型的字符串，即，返回“IAM Authorization”、“User Pool Authorization”、“Open ID Connect Authorization”或“API Key Authorization”。

## 返回值行为实用程序
<a name="utility-helpers-in-cloudwatch-logs-list-js"></a>

### 返回值行为实用程序列表
<a name="utility-helpers-in-behavior-list-js"></a>

 **`util.escapeJavaScript(String)`**  
以转义字符串的形式返回输入 JavaScript 字符串。

## 解析器授权实用程序
<a name="utility-helpers-in-resolver-auth-js"></a>

### 解析器授权实用程序列表
<a name="utility-helpers-in-resolver-auth-list-js"></a>

 **`util.unauthorized()`**  
针对被解析的字段引发 `Unauthorized`。可以在请求或响应映射模板中使用该实用程序，以确定是否允许调用方解析该字段。

# 内置模块
<a name="built-in-modules-js"></a>

模块是`APPSYNC_JS`运行时的一部分，提供实用程序来帮助编写 JavaScript 解析器和函数。有关示例和示例，请参阅[aws-appsync-resolver-samples](https://github.com/aws-samples/aws-appsync-resolver-samples) GitHub 存储库。

## DynamoDB 模块函数
<a name="built-in-ddb-modules"></a>

在与 DynamoDB 数据来源交互时，DynamoDB 模块函数提供增强的体验。您可以使用这些函数向 DynamoDB 数据来源发出请求，而无需添加类型映射。

模块是使用 `@aws-appsync/utils/dynamodb` 导入的：

```
// Modules are imported using @aws-appsync/utils/dynamodb
import * as ddb from '@aws-appsync/utils/dynamodb';
```

### 函数
<a name="built-in-ddb-modules-functions"></a>

#### 函数列表
<a name="built-in-ddb-modules-functions-list"></a>

 **` get<T>(payload: GetInput): DynamoDBGetItemRequest`**  
[输入](#built-in-ddb-modules-inputs)有关信息，请参阅 GetInput。
生成一个`DynamoDBGetItemRequest`对象以向 DynamoDB [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-getitem)发出请求。  

```
import { get } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	return get({ key: { id: ctx.args.id } });
}
```

 **`put<T>(payload): DynamoDBPutItemRequest`**  
生成一个`DynamoDBPutItemRequest`对象以向 DynamoDB [PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem)发出请求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	return ddb.put({ key: { id: util.autoId() }, item: ctx.args });
}
```

**`remove<T>(payload): DynamoDBDeleteItemRequest`**  
生成一个`DynamoDBDeleteItemRequest`对象以向 DynamoDB [DeleteItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-deleteitem)发出请求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	return ddb.remove({ key: { id: ctx.args.id } });
}
```

**`scan<T>(payload): DynamoDBScanRequest`**  
生成一个 `DynamoDBScanRequest` 以向 DynamoDB 发出 [Scan](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) 请求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken } = ctx.args;
	return ddb.scan({ limit, nextToken });
}
```

**`sync<T>(payload): DynamoDBSyncRequest`**  
生成一个 `DynamoDBSyncRequest` 对象以发出 [Sync](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-sync) 请求。该请求仅接收自上次查询以来更改的数据（增量更新）。只能向版本控制的 DynamoDB 数据来源发出请求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken, lastSync } = ctx.args;
	return ddb.sync({ limit, nextToken, lastSync });
}
```

**`update<T>(payload): DynamoDBUpdateItemRequest`**  
生成一个`DynamoDBUpdateItemRequest`对象以向 DynamoDB [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-updateitem)发出请求。

### 操作
<a name="built-in-ddb-modules-operations"></a>

通过使用操作帮助程序，您可以在更新期间对部分数据执行特定的操作。要开始使用，请从 `@aws-appsync/utils/dynamodb` 中导入 `operations`：

```
// Modules are imported using operations
import {operations} from '@aws-appsync/utils/dynamodb';
```

#### 操作列表
<a name="built-in-ddb-modules-operations-list"></a>

 **`add<T>(payload)`**  
在更新 DynamoDB 时添加新属性项目的帮助程序函数。  
**示例**  
要使用 ID 值将地址（街道、城市和邮政编码）添加到现有 DynamoDB 项目中，请运行以下命令：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		address: operations.add({
			street1: '123 Main St',
			city: 'New York',
			zip: '10001',
		}),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`append <T>(payload)`**  
将负载附加到 DynamoDB 中的现有列表的帮助程序函数。  
**示例**  
要在更新期间将新添加的朋友 IDs (`newFriendIds`) 添加到现有好友列表 (`friendsIds`) 中，请执行以下操作：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.append(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`decrement (by?)`**  
在更新 DynamoDB 时减少项目中的现有属性值的帮助程序函数。  
**示例**  
要将好友计数器 (`friendsCount`) 减少 10，请运行以下命令：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.decrement(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`increment (by?)`**  
在更新 DynamoDB 时增加项目中的现有属性值的帮助程序函数。  
**示例**  
要将好友计数器 (`friendsCount`) 增加 10，请运行以下命令：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.increment(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`prepend <T>(payload)`**  
在 DynamoDB 中的现有列表前面添加内容的帮助程序函数。  
**示例**  
要在更新期间将新添加的朋友 IDs (`newFriendIds`) 添加到现有好友列表 (`friendsIds`) 之前，请执行以下操作：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.prepend(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`replace <T>(payload)`**  
更新 DynamoDB 中的项目时替换现有属性的帮助程序函数。在您希望更新属性中的整个对象或子对象而不仅仅是负载中的键时，这是非常有用的。  
**示例**  
要替换 `info` 对象中的地址（街道、城市和邮政编码），请运行以下命令：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		info: {
			address: operations.replace({
				street1: '123 Main St',
				city: 'New York',
				zip: '10001',
			}),
		},
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`updateListItem <T>(payload, index)`**  
替换列表中的项目的帮助程序函数。  
**示例**  
在更新范围 (`newFriendIds`) 中，该示例使用 `updateListItem` 更新列表 (`friendsIds`) 中的第二项（索引 `1`，新 ID `102`）和第三项（索引 `2`，新 ID `112`）的 ID 值。  

```
import { update, operations as ops } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [
		ops.updateListItem('102', 1), ops.updateListItem('112', 2)
	];
	const updateObj = { friendsIds: newFriendIds };
	return update({ key: { id: 1 }, update: updateObj });
}
```

### 输入
<a name="built-in-ddb-modules-inputs"></a>

#### 输入列表
<a name="built-in-ddb-modules-inputs-list"></a>

 **`Type GetInput<T>`**  

```
GetInput<T>: { 
    consistentRead?: boolean; 
    key: DynamoDBKey<T>; 
}
```
**类型声明**  
+ `consistentRead?: boolean`（可选）

  一个可选的布尔值，用于指定您是否要在 DynamoDB 中执行强一致性读取。
+ `key: DynamoDBKey<T>`（必需）

  一个必需的参数，用于指定 DynamoDB 中的项目的键。DynamoDB 项目可能具有单个哈希键或者哈希键和排序键。

**`Type PutInput<T>`**  

```
PutInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T> | null; 
    customPartitionKey?: string; 
    item: Partial<T>; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**类型声明**  
+ `_version?: number`（可选）
+ `condition?: DynamoDBFilterObject<T> | null`（可选）

  在将对象放入 DynamoDB 表时，您可以选择指定一个条件表达式，以根据执行操作之前 DynamoDB 中的已有对象状态控制请求是否应成功。
+ `customPartitionKey?: string`（可选）

  如果启用，该字符串值修改启用了版本控制时增量同步表使用的 `ds_sk` 和 `ds_pk` 记录的格式。如果启用，还会启用 `populateIndexFields` 条目处理。
+ `item: Partial<T>`（必需）

  要放入 DynamoDB 的项目的其余属性。
+ `key: DynamoDBKey<T>`（必需）

  一个必需的参数，用于指定 DynamoDB 中执行放置的项目的键。DynamoDB 项目可能具有单个哈希键或者哈希键和排序键。
+ `populateIndexFields?: boolean`（可选）

  一个布尔值，在与 `customPartitionKey` 一起启用时，它为增量同步表中的每个记录创建新条目，具体来说是在 `gsi_ds_pk` 和 `gsi_ds_sk` 列中创建新条目。有关更多信息，请参阅《AWS AppSync 开发人员指南》中的[冲突检测和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。**

**`Type QueryInput<T>`**  

```
QueryInput<T>: ScanInput<T> & { 
    query: DynamoDBKeyCondition<Required<T>>; 
}
```
**类型声明**  
+ `query: DynamoDBKeyCondition<Required<T>>`（必需）

  指定描述要查询的项目的键条件。对于给定索引，分区键条件应该是相等，排序键的条件应该是比较或 `beginsWith`（在它是字符串时）。分区键和排序键仅支持数字和字符串类型。

  **示例**

  采用下面的 `User` 类型：

  ```
  type User = {
    id: string;
    name: string;
    age: number;
    isVerified: boolean;
    friendsIds: string[] 
  }
  ```

  查询只能包含以下字段：`id`、`name` 和 `age`：

  ```
  const query: QueryInput<User> = {
      name: { eq: 'John' },
      age: { gt: 20 },
  }
  ```

**`Type RemoveInput<T>`**  

```
RemoveInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**类型声明**  
+ `_version?: number`（可选）
+ `condition?: DynamoDBFilterObject<T>`（可选）

  在您删除 DynamoDB 中的对象时，您可以选择指定一个条件表达式，以根据执行操作之前 DynamoDB 中的已有对象状态控制请求是否应成功。

  **示例**

  以下示例是包含一个条件的 `DeleteItem` 表达式，只有在文档所有者与发出请求的用户匹配时，该条件才允许操作成功。

  ```
  type Task = {
    id: string;
    title: string;
    description: string;
    owner: string;
    isComplete: boolean;
  }
  const condition: DynamoDBFilterObject<Task> = {
    owner: { eq: 'XXXXXXXXXXXXXXXX' },
  }
  
  remove<Task>({
     key: {
       id: 'XXXXXXXXXXXXXXXX',
    },
    condition,
  });
  ```
+ `customPartitionKey?: string`（可选）

  如果启用，`customPartitionKey` 值修改启用了版本控制时增量同步表使用的 `ds_sk` 和 `ds_pk` 记录的格式。如果启用，还会启用 `populateIndexFields` 条目处理。
+ `key: DynamoDBKey<T>`（必需）

  一个必需的参数，用于指定在 DynamoDB 中删除的项目的键。DynamoDB 项目可能具有单个哈希键或者哈希键和排序键。

  **示例**

  如果 `User` 只有哈希键和用户 `id`，则该键如下所示：

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  }
  const key: DynamoDBKey<User> = {
  	id: 1,
  }
  ```

  如果表用户具有哈希键 (`id`) 和排序键 (`name`)，则该键如下所示：

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  	friendsIds: string[]
  }
  
  const key: DynamoDBKey<User> = {
  	id: 1,
  	name: 'XXXXXXXXXX',
  }
  ```
+ `populateIndexFields?: boolean`（可选）

  一个布尔值，在与 `customPartitionKey` 一起启用时，它为增量同步表中的每个记录创建新条目，具体来说是在 `gsi_ds_pk` 和 `gsi_ds_sk` 列中创建新条目。

**`Type ScanInput<T>`**  

```
ScanInput<T>: { 
    consistentRead?: boolean | null; 
    filter?: DynamoDBFilterObject<T> | null; 
    index?: string | null; 
    limit?: number | null; 
    nextToken?: string | null; 
    scanIndexForward?: boolean | null; 
    segment?: number; 
    select?: DynamoDBSelectAttributes; 
    totalSegments?: number; 
}
```
**类型声明**  
+ `consistentRead?: boolean | null`（可选）

  一个可选的布尔值，用于指示查询 DynamoDB 时的一致性读取。默认值为 `false`。
+ `filter?: DynamoDBFilterObject<T> | null`（可选）

  从表中检索结果后为结果应用的可选筛选条件。
+ `index?: string | null`（可选）

  要扫描的索引名称（可选）。
+ `limit?: number | null`（可选）

  要返回的最大结果数（可选）。
+ `nextToken?: string | null`（可选）

  一个可选的分页标记，用于在以前查询之后继续执行。这应已从之前查询中获得。
+ `scanIndexForward?: boolean | null`（可选）

  一个可选的布尔值，用于指示查询是按升序还是降序执行的。默认情况下，该值设置为 `true`。
+ `segment?: number`（可选）
+ `select?: DynamoDBSelectAttributes`（可选）

  从 DynamoDB 中返回的属性。默认情况下， AWS AppSync DynamoDB 解析器仅返回投影到索引中的属性。支持的值为：
  + `ALL_ATTRIBUTES`

    返回指定的表或索引中的所有项目属性。如果您查询本地二级索引，则 DynamoDB 从父表中为索引中的每个匹配项目获取整个项目。如果索引配置为投影所有项目属性，则可以从本地二级索引中获得所有数据，而不要求提取。
  + `ALL_PROJECTED_ATTRIBUTES`

    返回已投影到索引的所有属性。如果索引配置为投影所有属性，则此返回值等同于指定 `ALL_ATTRIBUTES`。
  + `SPECIFIC_ATTRIBUTES`

    仅返回 `ProjectionExpression` 中列出的属性。该返回值相当于指定 `ProjectionExpression` 而不指定 `AttributesToGet` 的任何值。
+ `totalSegments?: number`（可选）

**`Type DynamoDBSyncInput<T>`**  

```
DynamoDBSyncInput<T>: { 
    basePartitionKey?: string; 
    deltaIndexName?: string; 
    filter?: DynamoDBFilterObject<T> | null; 
    lastSync?: number; 
    limit?: number | null; 
    nextToken?: string | null; 
}
```
**类型声明**  
+ `basePartitionKey?: string`（可选）

  执行 Sync 操作时使用的基表的分区键。在表使用自定义分区键时，该字段允许执行 Sync 操作。
+ `deltaIndexName?: string`（可选）

  用于 Sync 操作的索引。在表使用自定义分区键时，需要使用该索引才能对整个增量存储表启用 Sync 操作。Sync 操作是对 GSI（在 `gsi_ds_pk` 和 `gsi_ds_sk` 上创建）执行的。
+ `filter?: DynamoDBFilterObject<T> | null`（可选）

  从表中检索结果后为结果应用的可选筛选条件。
+ `lastSync?: number`（可选）

  上次成功执行的 Sync 操作的启动时间（以纪元毫秒为单位）。如果指定，则仅返回 `lastSync` 之后更改的项目。只有在从初始 Sync 操作中检索所有页面后，才会填充该字段。如果省略，将返回基表的结果。否则，将返回增量表的结果。
+ `limit?: number | null`（可选）

  一次评估的最大项目数（可选）。如果省略，则默认限制将设置为 `100` 个项目。该字段的最大值为 `1000` 个项目。
+ `nextToken?: string | null`（可选）

**`Type DynamoDBUpdateInput<T>`**  

```
DynamoDBUpdateInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
    update: DynamoDBUpdateObject<T>; 
}
```
**类型声明**  
+ `_version?: number`（可选）
+ `condition?: DynamoDBFilterObject<T>`（可选）

  在您更新 DynamoDB 中的对象时，您可以选择指定一个条件表达式，以根据执行操作之前 DynamoDB 中的已有对象状态控制请求是否应成功。
+ `customPartitionKey?: string`（可选）

  如果启用，`customPartitionKey` 值修改启用了版本控制时增量同步表使用的 `ds_sk` 和 `ds_pk` 记录的格式。如果启用，还会启用 `populateIndexFields` 条目处理。
+ `key: DynamoDBKey<T>`（必需）

  一个必需的参数，用于指定在 DynamoDB 中更新的项目的键。DynamoDB 项目可能具有单个哈希键或者哈希键和排序键。
+ `populateIndexFields?: boolean`（可选）

  一个布尔值，在与 `customPartitionKey` 一起启用时，它为增量同步表中的每个记录创建新条目，具体来说是在 `gsi_ds_pk` 和 `gsi_ds_sk` 列中创建新条目。
+ `update: DynamoDBUpdateObject<T>`

  一个对象，它指定要更新的属性及其新值。可以将更新对象与 `add`、`remove`、`replace`、`increment`、`decrement`、`append`、`prepend` 和 `updateListItem` 一起使用。

## Amazon RDS 模块函数
<a name="built-in-rds-modules"></a>

在与使用 Amazon RDS 数据 API 配置的数据库进行交互时，Amazon RDS 模块函数可提供增强的体验。使用 `@aws-appsync/utils/rds` 导入模块：

```
import * as rds from '@aws-appsync/utils/rds';
```

也可以单独导入函数。例如，下面的导入使用 `sql`：

```
import { sql } from '@aws-appsync/utils/rds';
```

### 函数
<a name="built-in-rds-modules-functions"></a>

您可以使用 AWS AppSync RDS 模块的实用工具帮助程序与您的数据库进行交互。

#### Select
<a name="built-in-rds-modules-functions-select"></a>

`select` 实用程序会创建一条 `SELECT` 语句来查询您的关系数据库。

**基本用法**

在其基本形式中，您可以指定要查询的表：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

请注意，您也可以在表标识符中指定架构：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**指定列**

您可以使用 `columns` 属性指定列。如果未将其设置为某个值，则它默认为 `*`：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

您也可以指定列的表：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**限制和偏移**

您可以将 `limit` 和 `offset` 应用于查询：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**排序依据**

您可以使用 `orderBy` 属性对结果进行排序。提供指定列和可选 `dir` 属性的对象数组：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**筛选条件**

您可以使用特殊条件对象来构建筛选条件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

您也可以组合筛选条件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

您也可以创建 `OR` 语句：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用 `not` 来否定条件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用以下运算符来比较值：


| 
| 
| 运算符 | 说明 | 可能的值类型 | 
| --- |--- |--- |
| eq | Equal | 数字、字符串、布尔值 | 
| ne | Not equal | 数字、字符串、布尔值 | 
| le | Less than or equal | 数字，字符串 | 
| lt | Less than | 数字，字符串 | 
| ge | Greater than or equal | 数字，字符串 | 
| gt | Greater than | 数字，字符串 | 
| contains | like | 字符串 | 
| 不包含 | 不像 | 字符串 | 
| 开始于 | 以前缀开头 | 字符串 | 
| 介于 | 在两个值之间 | 数字，字符串 | 
| 属性存在 | 该属性不为空 | 数字、字符串、布尔值 | 
| size | 检查元素的长度 | 字符串 | 

#### Insert
<a name="built-in-rds-modules-functions-insert"></a>

`insert` 实用程序提供了一种通过 `INSERT` 操作在数据库中插入单行项目的简单方法。

**单个项目插入**

要插入项目，请指定表，然后传入您的值对象。对象键映射到您的表列。列名称会自动转义，并使用变量映射将值发送到数据库：

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**MySQL 用例**

您可以组合 `insert` 后跟 `select` 来检索您插入的行：

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Postgres 用例**

借助 Postgres，您可以使用 [https://www.postgresql.org/docs/current/dml-returning.html](https://www.postgresql.org/docs/current/dml-returning.html) 从插入的行中获取数据。它接受 `*` 或列名称数组：

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

#### 更新
<a name="built-in-rds-modules-functions-update"></a>

`update` 实用程序允许您更新现有行。您可以使用条件对象将更改应用于满足条件的所有行中的指定列。例如，假设我们有一个允许我们进行这种突变的架构。我们要将 `Person` 的 `name` 更新为 `id` 值 `3`，但仅限我们自 `2000` 年开始就已知道它们 (`known_since`)：

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

更新解析器如下所示：

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

我们可以在条件中添加一项检查，以确保只更新主键 `id` 等于 `3` 的行。同样，对于 Postgres `inserts`，您可以使用 `returning` 返回修改后的数据。

#### 删除
<a name="built-in-rds-modules-functions-remove"></a>

`remove` 实用程序允许您删除现有行。您可以在满足条件的所有行上使用条件对象。请注意，`delete`这是中的保留关键字 JavaScript。 `remove`应该改用：

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

### 转换
<a name="built-in-rds-modules-casting"></a>

在某些情况下，您可能希望在语句中使用更具体的正确对象类型。您可以使用提供的类型提示来指定参数的类型。 AWS AppSync 支持与数据 API [相同的类型提示](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint)。你可以使用 AWS AppSync `rds`模块中的`typeHint`函数来转换参数。

以下示例允许您将数组作为强制转换为 JSON 对象的值发送。我们使用 `->` 运算符来检索 JSON 数组中 `index` 为 `2` 的元素：

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

在处理和比较 `DATE`、`TIME` 和 `TIMESTAMP` 时，强制转换也很有用：

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

下面是另一个示例，显示如何发送当前日期和时间：

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**可用的类型提示**
+ `typeHint.DATE` – 相应的参数作为 `DATE` 类型的对象发送到数据库。接受的格式为 `YYYY-MM-DD`。
+ `typeHint.DECIMAL` – 相应的参数作为 `DECIMAL` 类型的对象发送到数据库。
+ `typeHint.JSON` – 相应的参数作为 `JSON` 类型的对象发送到数据库。
+ `typeHint.TIME` – 相应的字符串参数值作为 `TIME` 类型的对象发送到数据库。接受的格式为 `HH:MM:SS[.FFF]`。
+ `typeHint.TIMESTAMP` – 相应的字符串参数值作为 `TIMESTAMP` 类型的对象发送到数据库。接受的格式为 `YYYY-MM-DD HH:MM:SS[.FFF]`。
+ `typeHint.UUID` – 相应的字符串参数值作为 `UUID` 类型的对象发送到数据库。

# 运行时系统实用程序
<a name="runtime-utils-js"></a>

`runtime` 库提供一些实用程序以控制或修改解析器和函数的运行时属性。

## 运行时系统实用程序列表
<a name="runtime-utils-list-js"></a>

 **`runtime.earlyReturn(obj?: unknown, returnOptions?: {skipTo: 'END' | 'NEXT'}): never`**  
根据当前上下文，调用此函数将停止当前处理程序、 AWS AppSync 函数或解析器（Unit 或 Pipeline Resolver）的执行。将返回指定的对象以作为结果。  
+ 在 AWS AppSync 函数请求处理程序中调用时，会跳过数据源和响应处理程序，并调用下一个函数请求处理程序（如果这是最后一个 AWS AppSync 函数，则调用管道解析器响应处理程序）。
+ 在 AWS AppSync 管道解析器请求处理程序中调用时，将跳过管道执行，并立即调用管道解析器响应处理程序。
+ 如果在 `skipTo` 设置为“END”时返回了 `returnOptions`，则会跳过管道执行，并立即调用管道解析器响应处理程序。
+ 如果在 `skipTo` 设置为“NEXT”时返回了 `returnOptions`，则会跳过函数执行，并调用下一个管道处理程序。
**示例**  

```
import { runtime } from '@aws-appsync/utils'

export function request(ctx) {
  runtime.earlyReturn({ hello: 'world' })
  // code below is not executed
  return ctx.args
}

// never called because request returned early
export function response(ctx) {
  return ctx.result
}
```

# util.time 中的时间帮助程序
<a name="time-helpers-in-util-time-js"></a>

`util.time` 变量包含的日期时间方法有助于生成时间截，在不同的日期时间格式之间进行转换，并解析日期时间字符串。日期时间格式的语法基于该语法 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)，您可以参考该语法以获取更多文档。

## 时间实用程序列表
<a name="utility-helpers-in-time-list-js"></a>

 **`util.time.nowISO8601()`**  
以格式返回 UTC 的字符串表示[ISO8601形式](https://en.wikipedia.org/wiki/ISO_8601)。

 **`util.time.nowEpochSeconds()`**  
返回从 1970-01-01T00:00:00Z 纪元到现在的秒数。

 **`util.time.nowEpochMilliSeconds()`**  
返回从 1970-01-01T00:00:00Z 纪元到现在的毫秒数。

 **`util.time.nowFormatted(String)`**  
使用字符串输入类型指定的格式返回当前 UTC 时间戳的字符串。

 **`util.time.nowFormatted(String, String)`**  
使用字符串输入类型指定的格式和时区返回该时区当前时间戳的字符串。

 **`util.time.parseFormattedToEpochMilliSeconds(String, String)`**  
解析作为字符串传递的时间戳以及包含时区的格式，然后将时间戳作为自纪元以来的毫秒数返回。

 **`util.time.parseFormattedToEpochMilliSeconds(String, String, String)`**  
解析作为字符串传递的时间戳以及格式和时区，然后将时间戳作为自纪元以来的毫秒数返回。

 **`util.time.parseISO8601ToEpochMilliSeconds(String)`**  
解析作为字符串传递 ISO8601 的时间戳，然后返回自纪元以来的毫秒数的时间戳。

 **`util.time.epochMilliSecondsToSeconds(long)`**  
将纪元毫秒数时间戳转换为纪元秒数时间戳。

 **`util.time.epochMilliSecondsToISO8601(long)`**  
将纪元毫秒时间戳转换为时间戳。 ISO8601

 **`util.time.epochMilliSecondsToFormatted(long, String)`**  
将以长型形式传递的纪元毫秒数时间戳转换为根据提供的 UTC 格式设置的时间戳。

 **`util.time.epochMilliSecondsToFormatted(long, String, String)`**  
将以长型形式传递的纪元毫秒数时间戳转换为根据提供的时区和格式设置的时间戳。

# util.dynamodb 中的 DynamoDB 帮助程序
<a name="dynamodb-helpers-in-util-dynamodb-js"></a>

`util.dynamodb` 包含一些帮助程序方法，可以更轻松地在 Amazon DynamoDB 中写入和读取数据，例如自动类型映射和格式设置。

## toDynamoDB
<a name="utility-helpers-in-toDynamoDB-js"></a>

### toDynamoDB 实用程序列表
<a name="utility-helpers-in-toDynamoDB-list-js"></a>

 **`util.dynamodb.toDynamoDB(Object)`**   
DynamoDB 的常规对象转换工具，可以将输入对象转换为相应的 DynamoDB 表示形式。表示某些类型的方式是自主的：例如，使用列表 ("L") 而不使用集 ("SS", "NS", "BS")。这会返回一个描述 DynamoDB 属性值的对象。  
**字符串示例**  

```
Input:      util.dynamodb.toDynamoDB("foo")
Output:     { "S" : "foo" }
```
**数字示例**  

```
Input:      util.dynamodb.toDynamoDB(12345)
Output:     { "N" : 12345 }
```
**布尔值示例**  

```
Input:      util.dynamodb.toDynamoDB(true)
Output:     { "BOOL" : true }
```
**列表示例**  

```
Input:      util.dynamodb.toDynamoDB([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```
**映射示例**  

```
Input:      util.dynamodb.toDynamoDB({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

## toString 实用程序
<a name="utility-helpers-in-toString-js"></a>

### toString 实用程序列表
<a name="utility-helpers-in-toString-list-js"></a>

**`util.dynamodb.toString(String)`**  
将输入字符串转换为 DynamoDB 字符串格式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toString("foo")
Output:     { "S" : "foo" }
```

 **`util.dynamodb.toStringSet(List<String>)`**  
将包含字符串的列表转换为 DynamoDB 字符串集格式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toStringSet([ "foo", "bar", "baz" ])
Output:     { "SS" : [ "foo", "bar", "baz" ] }
```

## toNumber 实用程序
<a name="utility-helpers-in-toNumber-js"></a>

### toNumber 实用程序列表
<a name="utility-helpers-in-toNumber-list-js"></a>

 **`util.dynamodb.toNumber(Number)`**  
将数字转换为 DynamoDB 数字格式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toNumber(12345)
Output:     { "N" : 12345 }
```

 **`util.dynamodb.toNumberSet(List<Number>)`**  
将数字列表转换为 DynamoDB 数字集格式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toNumberSet([ 1, 23, 4.56 ])
Output:     { "NS" : [ 1, 23, 4.56 ] }
```

## toBinary 实用程序
<a name="utility-helpers-in-toBinary-js"></a>

### toBinary 实用程序列表
<a name="utility-helpers-in-toBinary-list-js"></a>

 **`util.dynamodb.toBinary(String)`**  
将编码为 Base64 字符串的二进制数据转换为 DynamoDB 二进制格式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toBinary("foo")
Output:     { "B" : "foo" }
```

 **`util.dynamodb.toBinarySet(List<String>)`**  
将编码为 Base64 字符串的二进制数据列表转换为 DynamoDB 二进制集格式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toBinarySet([ "foo", "bar", "baz" ])
Output:     { "BS" : [ "foo", "bar", "baz" ] }
```

## toBoolean 实用程序
<a name="utility-helpers-in-toBoolean-js"></a>

### toBoolean 实用程序列表
<a name="utility-helpers-in-toBoolean-list-js"></a>

 **`util.dynamodb.toBoolean(Boolean)`**  
将布尔值转换为相应的 DynamoDB 布尔值格式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toBoolean(true)
Output:     { "BOOL" : true }
```

## toNull 实用程序
<a name="utility-helpers-in-toNull-js"></a>

### toNull 实用程序列表
<a name="utility-helpers-in-toNull-list-js"></a>

 **`util.dynamodb.toNull()`**  
使用 DynamoDB Null 格式返回 Null。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toNull()
Output:     { "NULL" : null }
```

## toList 实用程序
<a name="utility-helpers-in-toList-js"></a>

### toList 实用程序列表
<a name="utility-helpers-in-toList-list-js"></a>

**`util.dynamodb.toList(List)`**  
将对象列表转换为 DynamoDB 列表格式。列表中的每个项目也会转换为相应的 DynamoDB 格式。表示某些嵌套对象的方式是自主的：例如，使用列表 ("L") 而不使用集 ("SS", "NS", "BS")。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toList([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```

## toMap 实用程序
<a name="utility-helpers-in-toMap-js"></a>

### toMap 实用程序列表
<a name="utility-helpers-in-toMap-list-js"></a>

 **`util.dynamodb.toMap(Map)`**  
将映射转换为 DynamoDB 映射格式。映射中的每个值也会转换为相应的 DynamoDB 格式。表示某些嵌套对象的方式是自主的：例如，使用列表 ("L") 而不使用集 ("SS", "NS", "BS")。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toMap({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

 **`util.dynamodb.toMapValues(Map)`**  
创建映射的副本，其中每个值都已转换为相应的 DynamoDB 格式。表示某些嵌套对象的方式是自主的：例如，使用列表 ("L") 而不使用集 ("SS", "NS", "BS")。  

```
Input:      util.dynamodb.toMapValues({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "foo"  : { "S" : "bar" },
               "baz"  : { "N" : 1234 },
               "beep" : {
                   "L" : [
                       { "S" : "boop" }
                   ]
               }
           }
```
这与 `util.dynamodb.toMap(Map)` 略有不同，因为它仅返回 DynamoDB 属性值内容，而不返回整个属性值本身。例如，以下语句是完全相同的：  

```
util.dynamodb.toMapValues(<map>)
util.dynamodb.toMap(<map>)("M")
```

## S3Object 实用程序
<a name="utility-helpers-in-S3Object-js"></a>

### S3Object 实用程序列表
<a name="utility-helpers-in-S3Object-list-js"></a>

**`util.dynamodb.toS3Object(String key, String bucket, String region)`**  
将键、存储桶和区域转换为 DynamoDB S3 对象表示形式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toS3Object("foo", "bar", region = "baz")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo", \"bucket\" : \"bar", \"region\" : \"baz" } }" }
```

**`util.dynamodb.toS3Object(String key, String bucket, String region, String version)`**  
将键、存储桶、区域和可选版本转换为 DynamoDB S3 对象表示形式。这会返回一个描述 DynamoDB 属性值的对象。  

```
Input:      util.dynamodb.toS3Object("foo", "bar", "baz", "beep")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" }
```

 **`util.dynamodb.fromS3ObjectJson(String)`**  
接受 DynamoDB S3 对象的字符串值，并返回包含键、存储桶、区域和可选版本的映射。  

```
Input:      util.dynamodb.fromS3ObjectJson({ "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" })
Output:     { "key" : "foo", "bucket" : "bar", "region" : "baz", "version" : "beep" }
```

# util.http 中的 HTTP 帮助程序
<a name="http-helpers-in-utils-http-js"></a>

`util.http` 实用程序提供一些帮助程序方法，可用于管理 HTTP 请求参数和添加响应标头。

## util.http 实用程序列表
<a name="http-helpers-in-utils-http-list-js"></a>

 **`util.http.copyHeaders(headers)`**  
从映射中复制标头，不包括以下受限制的 HTTP 标头：  
+ transfer-encoding
+ connection
+ host
+ expect
+ keep-alive
+ upgrade
+ proxy-authenticate
+ proxy-authorization
+ te
+ content-length

**`util.http.addResponseHeader(String, Object)`**  
添加单个自定义标头，其中包含响应的名称 (`String`) 和值 (`Object`)。适用以下限制：  
+ 除了 `copyHeaders(headers)` 的受限制标头列表外，标头名称不能与以下列出的任何名称相同：
  + Access-Control-Allow-Credentials
  + Access-Control-Allow-Origin
  + Access-Control-Expose-Headers
  + Access-Control-Max-Age
  + Access-Control-Allow-Methods
  + Access-Control-Allow-Headers
  + Vary
  + Content-Type
+ 标头名称不能以受限制的前缀 `x-amzn-` 或 `x-amz-` 开头。
+ 自定义响应标头大小不能超过 4 KB。这包括标头名称和值。
+ 对于每个 GraphQL 操作，您应该定义一次每个响应标头。不过，如果您多次定义具有相同名称的自定义标头，将在响应中显示最新的定义。无论命名如何，所有标头都会计入标头大小限制。
+ 系统会忽略名称为空或使用受限制名称 `(String)` 或 null 值 `(Object)` 的标头，并生成一个 `ResponseHeaderError` 错误，该错误会添加到操作的 `errors` 输出中。

```
export function request(ctx) {
  util.http.addResponseHeader('itemsCount', 7)
  util.http.addResponseHeader('render', ctx.args.render)
  return {}
}
```

**`util.http.addResponseHeaders(Map)`**  
将多个响应标头添加到来自指定的名称 `(String)` 和值 `(Object)` 映射的响应中。为 `addResponseHeader(String, Object)` 方法列出的相同限制也适用于该方法。  

```
export function request(ctx) {
  const headers = {
    headerInt: 12,
    headerString: 'stringValue',
    headerObject: {
      field1: 7,
      field2: 'string'
    }
  }
  util.http.addResponseHeaders(headers)
  return {}
}
```

# util.transform 中的转换帮助程序
<a name="transformation-helpers-in-utils-transform-js"></a>

`util.transform` 包含一些帮助程序方法，可以更轻松地对数据来源执行复杂的操作。

## 转换帮助程序实用程序列表
<a name="transformation-helpers-in-utils-transform-js-list"></a>

**`util.transform.toDynamoDBFilterExpression(filterObject: DynamoDBFilterObject) : string`**  
将输入字符串转换为筛选条件表达式以用于 DynamoDB。我们建议将 `toDynamoDBFilterExpression` 与[内置模块函数](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html)一起使用。

**`util.transform.toElasticsearchQueryDSL(object: OpenSearchQueryObject) : string`**  
将给定输入转换为其等效的 OpenSearch Query DSL 表达式，将其作为 JSON 字符串返回。  
**示例输入：**  

```
util.transform.toElasticsearchQueryDSL({
    "upvotes":{
        "ne":15,
        "range":[
            10,
            20
        ]
    },
    "title":{
        "eq":"hihihi",
        "wildcard":"h*i"
    }
  })
```
**示例输出：**  

```
{
    "bool":{
      "must":[
          {
            "bool":{
              "must":[
                  {
                    "bool":{
                      "must_not":{
                        "term":{
                          "upvotes":15
                        }
                      }
                    }
                  },
                  {
                    "range":{
                      "upvotes":{
                        "gte":10,
                        "lte":20
                      }
                    }
                  }
              ]
            }
          },
          {
            "bool":{
              "must":[
                  {
                    "term":{
                      "title":"hihihi"
                    }
                  },
                  {
                  "wildcard":{
                      "title":"h*i"
                    }
                  }
              ]
            }
          }
      ]
    }
}
```
默认运算符假定为 AND。

**`util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`**  
将 `Map` 输入对象转换为 `SubscriptionFilter` 表达式对象。`util.transform.toSubscriptionFilter` 方法用作 `extensions.setSubscriptionFilter()` 扩展的输入。有关更多信息，请参阅[扩展](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)。  
下面列出了参数和返回语句：  
*参数*  
+ `objFilter`: `SubscriptionFilterObject`

  转换为 `SubscriptionFilter` 表达式对象的 `Map` 输入对象。
+ `ignoredFields`:`SubscriptionFilterExcludeKeysType`（可选）

  第一个对象中将忽略的字段名称 `List`。
+ `rules`:`SubscriptionFilterRuleObject`（可选）

  在构建 `SubscriptionFilter` 表达式对象时包含的具有严格规则的 `Map` 输入对象。这些严格规则将包含在 `SubscriptionFilter` 表达式对象中，以便至少满足其中的一个规则才能通过订阅筛选条件。
*响应*  
返回 `[SubscriptionFilter](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)`。

**`util.transform.toSubscriptionFilter(Map, List)`**  
将 `Map` 输入对象转换为 `SubscriptionFilter` 表达式对象。`util.transform.toSubscriptionFilter` 方法用作 `extensions.setSubscriptionFilter()` 扩展的输入。有关更多信息，请参阅[扩展](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)。  
第一个参数是转换为 `SubscriptionFilter` 表达式对象的 `Map` 输入对象。第二个参数是字段名称 `List`，在构建 `SubscriptionFilter` 表达式对象时，将在第一个 `Map` 输入对象中忽略这些字段名称。

**`util.transform.toSubscriptionFilter(Map, List, Map)`**  
将 `Map` 输入对象转换为 `SubscriptionFilter` 表达式对象。`util.transform.toSubscriptionFilter` 方法用作 `extensions.setSubscriptionFilter()` 扩展的输入。有关更多信息，请参阅[扩展](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)。

**`util.transform.toDynamoDBConditionExpression(conditionObject)`**  
创建 DynamoDB 条件表达式。

## 订阅筛选条件参数
<a name="subscription-filter-arguments-js"></a>

下表介绍了如何定义以下实用程序的参数：
+ `Util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`

------
#### [ Argument 1: Map ]

参数 1 是一个 `Map` 对象，它具有以下键值：
+ 字段名称
+ "and"
+ "or"

对于作为键的字段名称，这些字段的条目条件采用 `"operator" : "value"` 格式。

以下示例说明了如何将条目添加到 `Map` 中：

```
"field_name" : {
                    "operator1" : value             
               }

## We can have multiple conditions for the same field_name: 

"field_name" : {
                    "operator1" : value             
                    "operator2" : value
                    .
                    .
                    .                  
               }
```

在一个字段具有两个或更多条件时，所有这些条件被视为使用 OR 运算。

输入 `Map` 也可以将 "and" 和 "or" 作为键，这意味着这些键中的所有条目应根据键使用 AND 或 OR 逻辑进行连接。键值 "and" 和 "or" 需要使用一个条件数组。

```
"and" : [
            
            {
                "field_name1" : {
                    "operator1" : value             
                }
             },
             
             {
                "field_name2" : {
                    "operator1" : value             
                }
             },
             .
             .
        ].
```

请注意，您可以嵌套 "and" 和 "or"。也就是说，您可以将 "and"/"or" 嵌套在另一个 "and"/"or" 块中。不过，这不适用于简单字段。

```
"and" : [
            
            {
                "field_name1" : {
                    "operator" : value             
                }
             },
             
             {
                "or" : [
                            {
                                "field_name2" : {
                                    "operator" : value             
                                }
                            },
                            
                            {
                                "field_name3" : {
                                    "operator" : value             
                                }
                            }
              
                        ].
```

以下示例显示使用 `util.transform.toSubscriptionFilter(Map) : Map` 的*参数 1* 的输入。

**输入**

参数 1：Map：

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 2000
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

**输出**

结果是一个 `Map` 对象：

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 2: List ]

参数 2 包含字段名称 `List`，在构建 `SubscriptionFilter` 表达式对象时，不应在输入 `Map`（参数 1）中考虑使用这些字段名称。`List` 也可以是空的。

以下示例显示使用 `util.transform.toSubscriptionFilter(Map, List) : Map` 的参数 1 和参数 2 的输入。

**输入**

参数 1：Map：

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

参数 2：List：

```
["percentageUp", "author"]
```

**输出**

结果是一个 `Map` 对象：

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 3: Map ]

参数 3 是一个将字段名称作为键值的 `Map` 对象（不能具有 "and" 或 "or"）。对于作为键的字段名称，这些字段的条件是采用 `"operator" : "value"` 格式的条目。与参数 1 不同，参数 3 不能在同一键中具有多个条件。此外，参数 3 没有 "and" 或 "or" 子句，因此，也不涉及嵌套。

参数 3 表示一组严格规则，这些规则将添加到 `SubscriptionFilter` 表达式对象中，以便至少满足**其中的一个**条件才能通过筛选条件。

```
{
  "fieldname1": {
    "operator": value
  },
  "fieldname2": {
    "operator": value
  }
}
.
.
.
```

以下示例显示使用 `util.transform.toSubscriptionFilter(Map, List, Map) : Map` 的*参数 1*、*参数 2* 和*参数 3* 的输入。

**输入**

参数 1：Map：

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "lt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

参数 2：List：

```
["percentageUp", "author"]
```

参数 3：Map：

```
{
  "upvotes": {
    "gte": 250
  },
  "author": {
    "eq": "Person1"
  }
}
```

**输出**

结果是一个 `Map` 对象：

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "upvotes",
          "operator": "gte",
          "value": 250
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Person1"
        }
      ]
    }
  ]
}
```

------

# util.str 中的字符串帮助程序
<a name="str-helpers-in-util-str-js"></a>

 `util.str` 包含一些方法以帮助执行常见的字符串操作。

## util.str 实用程序列表
<a name="str-helpers-in-util-str-list-js"></a>

 **`util.str.normalize(String, String)`**  
使用以下 4 种 unicode 规范化形式之一规范化字符串：NFC、NFD、NFKC 或 NFKD。第一个参数是要规范化的字符串。第二个参数是 "nfc"、"nfd"、"nfkc" 或 "nfkd"，它指定用于规范化过程的规范化类型。

# 扩展程序
<a name="extensions-js"></a>

`extensions` 包含一组在解析器中执行额外操作的方法。

## 缓存扩展
<a name="caching-extensions-js-list"></a>

**`extensions.evictFromApiCache(typeName: string, fieldName: string, keyValuePair: Record<string, any>) : Object`**  
从 AWS AppSync 服务器端缓存中移出一个项目。第一个参数是类型名称。第二个参数是字段名称。第三个参数是一个对象，其中包含指定缓存键值的键值对项目。您必须按照与缓存解析器的 `cachingKey` 中的缓存键相同的顺序，将项目放入对象中。有关缓存的更多信息，请参阅[缓存行为](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html#caching-behavior)。  
**示例 1：**  
该示例逐出为名为 `Query.allClasses` 的解析器缓存的项目，在该解析器上使用了名为 `context.arguments.semester` 的缓存键。在调用变更并运行解析器时，如果成功清除条目，则响应在扩展对象中包含一个 `apiCacheEntriesDeleted` 值以显示删除了多少条目。  

```
import { util, extensions } from '@aws-appsync/utils';

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
	extensions.evictFromApiCache('Query', 'allClasses', {
		'context.arguments.semester': ctx.args.semester,
	});
	return null;
}
```
该函数**仅**适用于变更，而不适用于查询。

## 订阅扩展
<a name="subscription-extensions-js-list"></a>

**`extensions.setSubscriptionFilter(filterJsonObject)`**  
定义增强的订阅筛选条件。每个订阅通知事件都会根据提供的订阅筛选条件进行评估，如果所有筛选条件的评估结果均为 `true`，则向客户端发送通知。参数是`filterJsonObject`（有关此参数的更多信息可以在下面的*参数： filterJsonObject*部分中找到。）。请参阅[增强订阅筛选](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html)。  
您只能在订阅解析器的响应处理程序中使用该扩展函数。此外，我们建议使用 `util.transform.toSubscriptionFilter` 创建筛选条件。

**`extensions.setSubscriptionInvalidationFilter(filterJsonObject)`**  
定义订阅失效筛选条件。根据失效负载评估订阅筛选条件，如果筛选条件的评估结果为 `true`，则使给定订阅失效。参数是`filterJsonObject`（有关此参数的更多信息可以在下面的*参数： filterJsonObject*部分中找到。）。请参阅[增强订阅筛选](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html)。  
您只能在订阅解析器的响应处理程序中使用该扩展函数。此外，我们建议使用 `util.transform.toSubscriptionFilter` 创建筛选条件。

**`extensions.invalidateSubscriptions(invalidationJsonObject)`**  
用于启动变更导致的订阅失效。参数是`invalidationJsonObject`（有关此参数的更多信息可以在下面的*参数： invalidationJsonObject*部分中找到。）。  
只能在变更解析器的响应映射模板中使用该扩展。  
您最多只能在任何单个请求中使用 5 个唯一的 `extensions.invalidateSubscriptions()` 方法调用。如果超过该限制，您将收到 GraphQL 错误。

## 论点： filterJsonObject
<a name="extensions-filterJsonObject-js"></a>

JSON 对象定义订阅或失效筛选条件。它是 `filterGroup` 中的筛选条件数组。每个筛选条件是单独筛选条件的集合。

```
{
    "filterGroup": [
        {
           "filters" : [
                 {
                    "fieldName" : "userId",
                    "operator" : "eq",
                    "value" : 1
                }
           ]
           
        },
        {
           "filters" : [
                {
                    "fieldName" : "group",
                    "operator" : "in",
                    "value" : ["Admin", "Developer"]
                }
           ]
           
        }
    ]
}
```

每个筛选条件具有三个属性：
+ `fieldName` - GraphQL 架构字段。
+ `operator` - 运算符类型。
+ `value` - 与订阅通知 `fieldName` 值进行比较的值。

以下是这些属性的分配示例：

```
{
 "fieldName" : "severity",
 "operator" : "le",
 "value" : context.result.severity
}
```

## 论点： invalidationJsonObject
<a name="extensions-invalidationJsonObject-js"></a>

`invalidationJsonObject` 定义以下内容：
+ `subscriptionField` - 要失效的 GraphQL 架构订阅。单个订阅（在 `subscriptionField` 中定义为字符串）被视为失效。
+ `payload` - 一个键值对列表，如果失效筛选条件根据其值评估的结果为 `true`，则将该列表作为使订阅失效的输入。

  在订阅解析器中定义的失效筛选条件根据 `payload` 值评估的结果为 `true` 时，以下示例导致使用 `onUserDelete` 订阅的订阅和连接的客户端失效。

  ```
  export const request = (ctx) => ({ payload: null });
  
  export function response(ctx) {
  	extensions.invalidateSubscriptions({
  		subscriptionField: 'onUserDelete',
  		payload: { group: 'Developer', type: 'Full-Time' },
  	});
  	return ctx.result;
  }
  ```

# util.xml 中的 XML 帮助程序
<a name="xml-helpers-in-util-xml-js"></a>

 `util.xml` 包含帮助进行 XML 字符串转换的方法。

## util.xml 实用程序列表
<a name="xml-helpers-in-util-xml-list-js"></a>

 **`util.xml.toMap(String) : Object`**  
将 XML 字符串转换为字典。  
**示例 1：**  

```
Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
    <id>1</id>
    <title>Getting started with GraphQL</title>
</post>
</posts>

Output (object):

{
    "posts":{
      "post":{
        "id":1,
        "title":"Getting started with GraphQL"
      }
    }
}
```
**示例 2：**  

```
Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
  <id>1</id>
  <title>Getting started with GraphQL</title>
</post>
<post>
  <id>2</id>
  <title>Getting started with AppSync</title>
</post>
</posts>

Output (JavaScript object):

{
    "posts":{
    "post":[
        {
            "id":1,
            "title":"Getting started with GraphQL"
        },
        {
            "id":2,
            "title":"Getting started with AppSync"
        }
    ]
    }
}
```

**`util.xml.toJsonString(String, Boolean?) : String`**  
将 XML 字符串转换为 JSON 字符串。这与 `toMap` 类似，只不过输出是字符串。如果您要直接转换 XML 响应并将其从 HTTP 对象返回到 JSON，这非常有用。您可以设置一个可选的布尔值参数，以确定是否要对 JSON 进行字符串编码。

# AWS AppSync JavaScript DynamoDB 的解析器函数参考
<a name="js-resolver-reference-dynamodb"></a>

D AWS AppSync ynamoDB 函数允许您使用 [GraphQL](https://graphql.org) 存储和检索账户中现有亚马逊 DynamoDB 表中的数据，方法是将传入的 GraphQL 请求映射到 DynamoDB 调用，然后将 DynamoDB 响应映射回 GraphQL。本节介绍了支持的 DynamoDB 操作的请求和响应处理程序：
+  [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-getitem.html)-该 GetItem 请求允许您告诉 DynamoDB 函数向 DynamoDB 发出 GetItem 请求，并允许您在 DynamoDB 中指定项目的密钥以及是否使用一致性读取。
+  [ PutItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-putitem.html)- PutItem 请求映射文档允许您告诉 DynamoDB 函数向 DynamoDB 发出 PutItem 请求，并允许您指定 DynamoDB 中项目的密钥、项目的全部内容（由键和属性值组成）以及操作成功所需的条件。
+  [ UpdateItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-updateitem.html)-该 UpdateItem 请求允许您告诉 DynamoDB 函数向 DynamoDB 发出 UpdateItem 请求，并允许您在 DynamoDB 中指定项目的密钥、描述如何在 DynamoDB 中更新项目的更新表达式以及操作成功的条件。
+  [ DeleteItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-deleteitem.html)-该 DeleteItem 请求允许您告诉 DynamoDB 函数向 DynamoDB 发出 DeleteItem 请求，并允许您在 DynamoDB 中指定项目的密钥以及操作成功的条件。
+  [Query](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-query.html)：通过使用 Query 请求对象，您可以指示 DynamoDB 解析器对 DynamoDB 发出 Query 请求，并可以指定键表达式、要使用的索引、其他筛选条件、要返回的项目数量、是否使用一致性读取、查询方向（向前或向后）以及分页标记。
+  [Scan](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-scan.html)：通过使用 Scan 请求，您可以指示 DynamoDB 函数对 DynamoDB 发出 Scan 请求，并可以指定排除结果的筛选条件、要使用的索引、要返回的项目数量、是否使用一致性读取、分页令牌和并行扫描。
+  [Sync](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-sync.html)：通过使用 Sync 请求对象，您可以从 DynamoDB 表中检索所有结果，然后仅接收自上次查询以来更改的数据（增量更新）。只能向版本控制的 DynamoDB 数据来源发出 Sync 请求。您可以指定排除结果的筛选条件、要返回的项目数量、分页令牌以及上次同步操作的启动时间。
+  [ BatchGetItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-batch-get-item.html)- BatchGetItem 请求对象允许您告诉 DynamoDB 函数向 DynamoDB 发出 BatchGetItem 请求，以检索多个项目，可能跨多个表。对于此请求对象，您必须指定要从中检索项目的表名称，以及要从每个表中检索的项目的键。
+  [ BatchDeleteItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-batch-delete-item.html)- BatchDeleteItem 请求对象允许您告诉 DynamoDB 函数向 DynamoDB 发出 BatchWriteItem 请求，要求删除多个项目，可能跨多个表。对于此请求对象，您必须指定要从中删除项目的表名称，以及要从每个表中删除的项目的键。
+  [ BatchPutItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-batch-put-item.html)- BatchPutItem 请求对象允许您告诉 DynamoDB 函数向 DynamoDB 发出 BatchWriteItem 请求，要求将多个项目放置在多个表中。对于此请求对象，您必须指定要放置项目的表名称和要放入每个表中的完整项目。
+  [ TransactGetItems ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-transact-get-items.html)- TransactGetItems 请求对象允许您告诉 DynamoDB 函数向 DynamoDB 发出 TransactGetItems 请求，以检索多个项目，可能跨多个表。对于此请求对象，您必须指定要从中检索项目的每个请求项目的表名称，以及要从每个表中检索的每个请求项目的键。
+  [ TransactWriteItems ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-transact-write-items.html)- TransactWriteItems 请求对象允许您告诉 DynamoDB 函数向 DynamoDB 发出写入多个项目（可能写入多个表）的 TransactWriteItems 请求。对于此请求对象，您必须指定每个请求项目的目标表名称、要执行的每个请求项目的操作以及要写入的每个请求项目的键。
+  [类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-typed-values-request.html)-详细了解 DynamoDB 类型如何集成到请求中。 AWS AppSync 
+  [类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-typed-values-responses.html)：详细了解 DynamoDB 类型如何在响应有效载荷中自动转换为 GraphQL 或 JSON。
+  [筛选条件](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-filter.html)：详细了解查询和扫描操作的筛选条件。
+  [条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-condition-expressions.html)-了解有关 PutItem UpdateItem、和 DeleteItem 运算的条件表达式的更多信息。
+  [交易条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions.html)-了解有关 TransactWriteItems 操作条件表达式的更多信息。
+  [投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-projections.html)：详细了解如何在读取操作中指定属性。

# GetItem
<a name="js-aws-appsync-resolver-reference-dynamodb-getitem"></a>

该`GetItem`请求允许您告诉 AWS AppSync DynamoDB 函数向 DynamoDB 发出`GetItem`请求，并允许您指定：
+ DynamoDB 中的项目的键
+ 是否使用一致性读取

`GetItem` 请求具有以下结构：

```
type DynamoDBGetItem = {
  operation: 'GetItem';
  key: { [key: string]: any };
  consistentRead?: ConsistentRead;
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

字段定义如下：

## GetItem 字段
<a name="js-getitem-list"></a>

### GetItem 字段列表
<a name="js-getitem-list-col"></a>

 **`operation`**   
要执行的 DynamoDB 操作。要执行 `GetItem` DynamoDB 操作，该字段必须设置为 `GetItem`。该值为必填项。

 **`key`**   
DynamoDB 中的项目的键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。

 **`consistentRead`**   
是否对 DynamoDB 执行强一致性读取。这是可选的，默认值为 `false`。

**`projection`**  
用于指定从 DynamoDB 操作返回的属性的投影。有关投影的更多信息，请参阅[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。该字段是可选的。

从 DynamoDB 返回的项目自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

有关 JavaScript 解析器的更多信息，请参阅解析[JavaScript 器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)概述。

## 示例
<a name="js-example"></a>

以下示例是 GraphQL 查询 `getThing(foo: String!, bar: String!)` 的函数请求处理程序：

```
export function request(ctx) {
  const {foo, bar} = ctx.args
  return {
    operation : "GetItem",
    key : util.dynamodb.toMapValues({foo, bar}),
    consistentRead : true
  }
}
```

有关 DynamoDB `GetItem` API 的更多信息，请参阅 [DynamoDB API 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)。

# PutItem
<a name="js-aws-appsync-resolver-reference-dynamodb-putitem"></a>

`PutItem`请求映射文档允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出`PutItem`请求，并允许您指定以下内容：
+ DynamoDB 中的项目的键
+ 项目的完整内容（包括 `key` 和 `attributeValues`）
+ 操作成功执行的条件

`PutItem` 请求具有以下结构：

```
type DynamoDBPutItemRequest = {
  operation: 'PutItem';
  key: { [key: string]: any };
  attributeValues: { [key: string]: any};
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

字段定义如下：

## PutItem 字段
<a name="js-putitem-list"></a>

### PutItem 字段列表
<a name="js-putitem-list-col"></a>

 **`operation`**   
要执行的 DynamoDB 操作。要执行 `PutItem` DynamoDB 操作，该字段必须设置为 `PutItem`。该值为必填项。

 **`key`**   
DynamoDB 中的项目的键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。

 **`attributeValues`**   
要放入 DynamoDB 中的项目的其余属性。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该字段是可选的。

 **`condition`**   
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `PutItem` 请求将覆盖该项目的任何现有条目。有关条件的更多信息，请参阅[条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions)。该值为可选项。

 **`_version`**   
表示项目的最新已知版本的数值。该值为可选项。该字段用于*冲突检测*，仅受版本控制的数据来源支持。

**`customPartitionKey`**  
启用后，此字符串值将修改启用版本控制后增量同步表使用的`ds_sk`和`ds_pk`记录的格式（有关更多信息，请参阅*《AWS AppSync 开发人员指南》*中的[冲突检测和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)）。如果启用，还会启用 `populateIndexFields` 条目处理。该字段是可选的。

**`populateIndexFields`**  
一个布尔值，在**与 `customPartitionKey` 一起**启用时，它为增量同步表中的每个记录创建新条目，具体来说是在 `gsi_ds_pk` 和 `gsi_ds_sk` 列中创建新条目。有关更多信息，请参阅《AWS AppSync 开发人员指南》中的[冲突检测和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。**该字段是可选的。  
写入到 DynamoDB 的项目自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

写入到 DynamoDB 的项目自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

有关 JavaScript 解析器的更多信息，请参阅解析[JavaScript器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)概述。

## 示例 1
<a name="js-example-1"></a>

以下示例是 GraphQL 变更 `updateThing(foo: String!, bar: String!, name: String!, version: Int!)` 的函数请求处理程序。

如果带指定键的项目不存在，则会创建它。如果带指定键的项已存在，则会覆盖它。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

## 示例 2
<a name="js-example-2"></a>

以下示例是 GraphQL 变更 `updateThing(foo: String!, bar: String!, name: String!, expectedVersion: Int!)` 的函数请求处理程序。

该示例验证当前位于 DynamoDB 中的项目的 `version` 字段是否设置为 `expectedVersion`。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, name, expectedVersion } = ctx.args;
  const values = { name, version: expectedVersion + 1 };
  let condition = util.transform.toDynamoDBConditionExpression({
    version: { eq: expectedVersion },
  });

  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ foo, bar }),
    attributeValues: util.dynamodb.toMapValues(values),
    condition,
  };
}
```

有关 DynamoDB `PutItem` API 的更多信息，请参阅 [DynamoDB API 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)。

# UpdateItem
<a name="js-aws-appsync-resolver-reference-dynamodb-updateitem"></a>

该`UpdateItem`请求允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出`UpdateItem`请求，并允许您指定以下内容：
+ DynamoDB 中的项目的键
+ 描述如何更新 DynamoDB 中的项目的更新表达式
+ 操作成功执行的条件

`UpdateItem` 请求具有以下结构：

```
type DynamoDBUpdateItemRequest = {
  operation: 'UpdateItem';
  key: { [key: string]: any };
  update: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

字段定义如下：

## UpdateItem 字段
<a name="js-updateitem-list"></a>

### UpdateItem 字段列表
<a name="js-updateitem-list-col"></a>

 **`operation`**   
要执行的 DynamoDB 操作。要执行 `UpdateItem` DynamoDB 操作，该字段必须设置为 `UpdateItem`。该值为必填项。

 **`key`**   
DynamoDB 中的项目的键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。

 **`update`**   
`update` 部分用于指定一个更新表达式，以描述如何更新 DynamoDB 中的项目。有关如何编写更新表达式的更多信息，请参阅 [DynamoDB 文档 UpdateExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)。此部分是必需的。  
`update` 部分有三个组成部分：    
** `expression` **  
更新表达式。该值为必填项。  
** `expressionNames` **  
以键值对形式替换表达式属性*名称* 占位符。键对应于 `expression` 中使用的名称占位符，值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 `expression` 中使用的表达式属性名称占位符的替换内容。  
** `expressionValues` **  
以键值对形式替换表达式属性*值* 占位符。键对应于 `expression` 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。必须指定此值。该字段是可选的，只应填充 `expression` 中使用的表达式属性值占位符的替换内容。

 **`condition`**   
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `UpdateItem` 请求将更新现有条目，而不考虑其当前状态。有关条件的更多信息，请参阅[条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions)。该值为可选项。

 **`_version`**   
表示项目的最新已知版本的数值。该值为可选项。该字段用于*冲突检测*，仅受版本控制的数据来源支持。

**`customPartitionKey`**  
启用后，此字符串值将修改启用版本控制后增量同步表使用的`ds_sk`和`ds_pk`记录的格式（有关更多信息，请参阅*《AWS AppSync 开发人员指南》*中的[冲突检测和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)）。如果启用，还会启用 `populateIndexFields` 条目处理。该字段是可选的。

**`populateIndexFields`**  
一个布尔值，在**与 `customPartitionKey` 一起**启用时，它为增量同步表中的每个记录创建新条目，具体来说是在 `gsi_ds_pk` 和 `gsi_ds_sk` 列中创建新条目。有关更多信息，请参阅《AWS AppSync 开发人员指南》中的[冲突检测和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。**该字段是可选的。

在 DynamoDB 中更新的项目自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

有关 JavaScript 解析器的更多信息，请参阅解析[JavaScript 器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)概述。

## 示例 1
<a name="js-id3"></a>

以下示例是 GraphQL 变更 `upvote(id: ID!)` 的函数请求处理程序。

在该示例中，DynamoDB 中的项目的 `upvotes` 和 `version` 字段递增 1。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id } = ctx.args;
  return {
    operation: 'UpdateItem',
    key: util.dynamodb.toMapValues({ id }),
    update: {
      expression: 'ADD #votefield :plusOne, version :plusOne',
      expressionNames: { '#votefield': 'upvotes' },
      expressionValues: { ':plusOne': { N: 1 } },
    },
  };
}
```

## 示例 2
<a name="js-id4"></a>

以下示例是 GraphQL 变更 `updateItem(id: ID!, title: String, author: String, expectedVersion: Int!)` 的函数请求处理程序。

这是一个复杂的示例，用于检查参数并动态生成更新表达式，此表达式仅包含由客户端提供的参数。例如，如果省略了 `title` 和 `author`，则不会更新它们。如果指定了一个参数，但该参数的值为 `null`，则会从 DynamoDB 上的对象中删除该字段。最后，该操作具有一个条件，用于验证目前位于 DynamoDB 中的项目的 `version` 字段是否设置为 `expectedVersion`：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { args: { input: { id, ...values } } } = ctx;

  const condition = {
    id: { attributeExists: true },
    version: { eq: values.expectedVersion },
  };
  values.expectedVersion += 1;
  return dynamodbUpdateRequest({ keys: { id }, values, condition });
}


/**
 * Helper function to update an item
 * @returns an UpdateItem request
 */
function dynamodbUpdateRequest(params) {
  const { keys, values, condition: inCondObj } = params;

  const sets = [];
  const removes = [];
  const expressionNames = {};
  const expValues = {};

  // Iterate through the keys of the values
  for (const [key, value] of Object.entries(values)) {
    expressionNames[`#${key}`] = key;
    if (value) {
      sets.push(`#${key} = :${key}`);
      expValues[`:${key}`] = value;
    } else {
      removes.push(`#${key}`);
    }
  }

  let expression = sets.length ? `SET ${sets.join(', ')}` : '';
  expression += removes.length ? ` REMOVE ${removes.join(', ')}` : '';

  const condition = JSON.parse(
    util.transform.toDynamoDBConditionExpression(inCondObj)
  );

  return {
    operation: 'UpdateItem',
    key: util.dynamodb.toMapValues(keys),
    condition,
    update: {
      expression,
      expressionNames,
      expressionValues: util.dynamodb.toMapValues(expValues),
    },
  };
}
```

有关 DynamoDB `UpdateItem` API 的更多信息，请参阅 [DynamoDB API 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)。

# DeleteItem
<a name="js-aws-appsync-resolver-reference-dynamodb-deleteitem"></a>

该`DeleteItem`请求允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出`DeleteItem`请求，并允许您指定以下内容：
+ DynamoDB 中的项目的键
+ 操作成功执行的条件

`DeleteItem` 请求具有以下结构：

```
type DynamoDBDeleteItemRequest = {
  operation: 'DeleteItem';
  key: { [key: string]: any };
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

字段定义如下：

## DeleteItem 字段
<a name="js-deleteitem-list"></a>

### DeleteItem 字段列表
<a name="js-deleteitem-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `DeleteItem` DynamoDB 操作，该字段必须设置为 `DeleteItem`。该值为必填项。

** `key` **  
DynamoDB 中的项目的键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。

** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `DeleteItem` 请求将删除项目，而不考虑其当前状态。有关条件的更多信息，请参阅[条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions)。该值为可选项。

** `_version` **  
表示项目的最新已知版本的数值。该值为可选项。该字段用于*冲突检测*，仅受版本控制的数据来源支持。

**`customPartitionKey`**  
启用后，此字符串值将修改启用版本控制后增量同步表使用的`ds_sk`和`ds_pk`记录的格式（有关更多信息，请参阅*《AWS AppSync 开发人员指南》*中的[冲突检测和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)）。如果启用，还会启用 `populateIndexFields` 条目处理。该字段是可选的。

**`populateIndexFields`**  
一个布尔值，在**与 `customPartitionKey` 一起**启用时，它为增量同步表中的每个记录创建新条目，具体来说是在 `gsi_ds_pk` 和 `gsi_ds_sk` 列中创建新条目。有关更多信息，请参阅《AWS AppSync 开发人员指南》中的[冲突检测和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。**该字段是可选的。

从 DynamoDB 中删除的项目自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

有关 JavaScript 解析器的更多信息，请参阅解析[JavaScript 器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)概述。

## 示例 1
<a name="js-id6"></a>

以下示例是 GraphQL 变更 `deleteItem(id: ID!)` 的函数请求处理程序。如果具有此 ID 的项目存在，它将被删除。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'DeleteItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

## 示例 2
<a name="js-id7"></a>

以下示例是 GraphQL 变更 `deleteItem(id: ID!, expectedVersion: Int!)` 的函数请求处理程序。如果具有此 ID 的项目存在，它将被删除，但仅当其 `version` 字段设置为 `expectedVersion` 时：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { id, expectedVersion } = ctx.args;
  const condition = {
    id: { attributeExists: true },
    version: { eq: expectedVersion },
  };
  return {
    operation: 'DeleteItem',
    key: util.dynamodb.toMapValues({ id }),
    condition: util.transform.toDynamoDBConditionExpression(condition),
  };
}
```

有关 DynamoDB `DeleteItem` API 的更多信息，请参阅 [DynamoDB API 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html)。

# Query
<a name="js-aws-appsync-resolver-reference-dynamodb-query"></a>

`Query`请求对象允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB 发出`Query`请求，并允许您指定以下内容：
+ 键表达式
+ 要使用的索引
+ 任何额外的筛选条件
+ 要返回多少个项目
+ 是否使用一致性读取
+ 查询方向（向前或向后）
+ 分页标记

`Query` 请求对象具有以下结构：

```
type DynamoDBQueryRequest = {
  operation: 'Query';
  query: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  index?: string;
  nextToken?: string;
  limit?: number;
  scanIndexForward?: boolean;
  consistentRead?: boolean;
  select?: 'ALL_ATTRIBUTES' | 'ALL_PROJECTED_ATTRIBUTES' | 'SPECIFIC_ATTRIBUTES';
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

字段定义如下：

## Query 字段
<a name="js-query-list"></a>

### Query 字段列表
<a name="js-query-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `Query` DynamoDB 操作，该字段必须设置为 `Query`。该值为必填项。

** `query` **  
`query` 部分用于指定一个键条件表达式，用于描述要从 DynamoDB 中检索哪些项目。有关如何编写关键条件表达式的更多信息，请参阅 [DynamoDB 文档 KeyConditions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html)。必须指定此部分。    
** `expression` **  
查询表达式。必须指定该字段。  
** `expressionNames` **  
以键值对形式替换表达式属性*名称* 占位符。键对应于 `expression` 中使用的名称占位符，值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 `expression` 中使用的表达式属性名称占位符的替换内容。  
** `expressionValues` **  
以键值对形式替换表达式属性*值* 占位符。键对应于 `expression` 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。该字段是可选的，只应填充 `expression` 中使用的表达式属性值占位符的替换内容。

** `filter` **  
另一个筛选条件，该筛选条件可用于在从 DynamoDB 返回结果之前先筛选结果。有关筛选条件的更多信息，请参阅[筛选条件](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)。该字段是可选的。

** `index` **  
要查询的索引的名称。除了哈希键的主键索引以外，您还可以通过 DynamoDB 查询操作扫描本地二级索引和全局二级索引。如果指定，这会指示 DynamoDB 查询指定的索引。如果省略，则将查询主键索引。

** `nextToken` **  
继续之前查询的分页标记。这应已从之前查询中获得。该字段是可选的。

** `limit` **  
要评估的最大项目数（不一定是匹配项目数）。该字段是可选的。

** `scanIndexForward` **  
一个布尔值，指示是向前还是向后查询。该字段是可选的，默认值为 `true`。

** `consistentRead` **  
一个布尔值，用于指示在查询 DynamoDB 时是否使用一致性读取。该字段是可选的，默认值为 `false`。

** `select` **  
默认情况下， AWS AppSync DynamoDB 解析器仅返回投影到索引中的属性。如果需要更多属性，则可以设置该字段。该字段是可选的。支持的值为：    
** `ALL_ATTRIBUTES` **  
返回指定的表或索引中的所有项目属性。如果您查询本地二级索引，则 DynamoDB 从父表中为索引中的每个匹配项目获取整个项目。如果索引配置为投影所有项目属性，则可以从本地二级索引中获得所有数据，而不要求提取。  
** `ALL_PROJECTED_ATTRIBUTES` **  
仅在查询索引时才允许。检索已投影到索引的所有属性。如果索引配置为投影所有属性，则此返回值等同于指定 `ALL_ATTRIBUTES`。  
**`SPECIFIC_ATTRIBUTES`**  
仅返回 `projection` 的 `expression` 中列出的属性。该返回值相当于指定 `projection` 的 `Select`，而不指定 `expression` 的任何值。

**`projection`**  
用于指定从 DynamoDB 操作返回的属性的投影。有关投影的更多信息，请参阅[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。该字段是可选的。

来自 DynamoDB 的结果自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

有关 JavaScript 解析器的更多信息，请参阅解析[JavaScript 器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)概述。

结果的结构如下所示：

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

字段定义如下：

** `items` **  
包含 DynamoDB 查询返回的项目的列表。

** `nextToken` **  
如果可能有更多结果，则 `nextToken` 包含一个分页标记，您可以在另一个请求中使用该标记。请注意，它 AWS AppSync 会加密并混淆从 DynamoDB 返回的分页令牌。这可防止您的表数据无意中泄露给调用方。另请注意，这些分页标记不能在不同的函数或解析器中使用。

** `scannedCount` **  
在应用筛选表达式（如果有）之前与查询条件表达式匹配的项目的数量。

## 示例
<a name="js-id9"></a>

以下示例是 GraphQL 查询 `getPosts(owner: ID!)` 的函数请求处理程序。

在本示例中，将对表的全局二级索引执行查询，以返回指定的 ID 拥有的所有文章。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { owner } = ctx.args;
  return {
    operation: 'Query',
    query: {
      expression: 'ownerId = :ownerId',
      expressionValues: util.dynamodb.toMapValues({ ':ownerId': owner }),
    },
    index: 'owner-index',
  };
}
```

有关 DynamoDB `Query` API 的更多信息，请参阅 [DynamoDB API 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)。

# Scan
<a name="js-aws-appsync-resolver-reference-dynamodb-scan"></a>

该`Scan`请求允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出`Scan`请求，并允许您指定以下内容：
+ 排除结果的筛选条件
+ 要使用的索引
+ 要返回多少个项目
+ 是否使用一致性读取
+ 分页标记
+ 并行扫描

`Scan` 请求对象具有以下结构：

```
type DynamoDBScanRequest = {
  operation: 'Scan';
  index?: string;
  limit?: number;
  consistentRead?: boolean;
  nextToken?: string;
  totalSegments?: number;
  segment?: number;
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

字段定义如下：

## Scan 字段
<a name="js-scan-list"></a>

### Scan 字段列表
<a name="js-scan-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `Scan` DynamoDB 操作，该字段必须设置为 `Scan`。该值为必填项。

** `filter` **  
一个筛选条件，可用于在返回来自 DynamoDB 的结果之前对其进行筛选。有关筛选条件的更多信息，请参阅[筛选条件](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)。该字段是可选的。

** `index` **  
要查询的索引的名称。除了哈希键的主键索引以外，您还可以通过 DynamoDB 查询操作扫描本地二级索引和全局二级索引。如果指定，这会指示 DynamoDB 查询指定的索引。如果省略，则将查询主键索引。

** `limit` **  
单次评估的最大项目数。该字段是可选的。

** `consistentRead` **  
一个布尔值，用于指示在查询 DynamoDB 时是否使用一致性读取。该字段是可选的，默认值为 `false`。

** `nextToken` **  
继续之前查询的分页标记。这应已从之前查询中获得。该字段是可选的。

** `select` **  
默认情况下， AWS AppSync DynamoDB 函数仅返回投影到索引中的任何属性。如果需要更多属性，则可以设置该字段。该字段是可选的。支持的值为：    
** `ALL_ATTRIBUTES` **  
返回指定的表或索引中的所有项目属性。如果您查询本地二级索引，则 DynamoDB 从父表中为索引中的每个匹配项目获取整个项目。如果索引配置为投影所有项目属性，则可以从本地二级索引中获得所有数据，而不要求提取。  
** `ALL_PROJECTED_ATTRIBUTES` **  
仅在查询索引时才允许。检索已投影到索引的所有属性。如果索引配置为投影所有属性，则此返回值等同于指定 `ALL_ATTRIBUTES`。  
**`SPECIFIC_ATTRIBUTES`**  
仅返回 `projection` 的 `expression` 中列出的属性。该返回值相当于指定 `projection` 的 `Select`，而不指定 `expression` 的任何值。

** `totalSegments` **  
执行并行扫描时对表进行分区的分段数。该字段是可选的，但如果指定 `segment`，则必须指定该字段。

** `segment` **  
执行并行扫描时，此操作中的表分段。该字段是可选的，但如果指定 `totalSegments`，则必须指定该字段。

**`projection`**  
用于指定从 DynamoDB 操作返回的属性的投影。有关投影的更多信息，请参阅[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。该字段是可选的。

DynamoDB 扫描返回的结果自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

有关 JavaScript 解析器的更多信息，请参阅解析[JavaScript 器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)概述。

结果的结构如下所示：

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

字段定义如下：

** `items` **  
包含 DynamoDB 扫描返回的项目的列表。

** `nextToken` **  
如果可能有更多结果，则`nextToken`包含可在其他请求中使用的分页令牌。 AWS AppSync 加密并混淆从 DynamoDB 返回的分页令牌。这可防止您的表数据无意中泄露给调用方。此外，这些分页标记不能在不同的函数或解析器中使用。

** `scannedCount` **  
在应用筛选条件表达式（如果有）之前 DynamoDB 检索的项目数。

## 示例 1
<a name="js-id11"></a>

以下示例是 GraphQL 查询 `allPosts` 的函数请求处理程序。

在本示例中，将返回表中的所有条目。

```
export function request(ctx) {
  return { operation: 'Scan' };
}
```

## 示例 2
<a name="js-id12"></a>

以下示例是 GraphQL 查询 `postsMatching(title: String!)` 的函数请求处理程序。

在本示例中，将返回表中标题以 `title` 参数开头的所有条目。

```
export function request(ctx) {
  const { title } = ctx.args;
  const filter = { filter: { beginsWith: title } };
  return {
    operation: 'Scan',
    filter: JSON.parse(util.transform.toDynamoDBFilterExpression(filter)),
  };
}
```

有关 DynamoDB `Scan` API 的更多信息，请参阅 [DynamoDB API 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html)。

# 同步
<a name="js-aws-appsync-resolver-reference-dynamodb-sync"></a>

通过使用 `Sync` 请求对象，您可以从 DynamoDB 表中检索所有结果，然后仅接收自上次查询以来更改的数据（增量更新）。只能对版本控制的 DynamoDB 数据来源发出 `Sync` 请求。您可以指定以下内容：
+ 排除结果的筛选条件
+ 要返回多少个项目
+ 分页标记
+ 上次 `Sync` 操作开始时间

`Sync` 请求对象具有以下结构：

```
type DynamoDBSyncRequest = {
  operation: 'Sync';
  basePartitionKey?: string;
  deltaIndexName?: string;
  limit?: number;
  nextToken?: string;
  lastSync?: number;
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
};
```

字段定义如下：

## Sync 字段
<a name="js-sync-list"></a>

### Sync 字段列表
<a name="js-sync-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `Sync` 操作，该字段必须设置为 `Sync`。该值为必填项。

** `filter` **  
一个筛选条件，可用于在返回来自 DynamoDB 的结果之前对其进行筛选。有关筛选条件的更多信息，请参阅[筛选条件](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)。该字段是可选的。

** `limit` **  
单次评估的最大项目数。该字段是可选的。如果省略，则默认限制将设置为 `100` 个项目。该字段的最大值为 `1000` 个项目。

** `nextToken` **  
继续之前查询的分页标记。这应已从之前查询中获得。该字段是可选的。

** `lastSync` **  
最后一次成功 `Sync` 操作开始的时刻（以纪元毫秒为单位）。如果指定，则仅返回 `lastSync` 之后更改的项目。该字段是可选的，只有在从初始 `Sync` 操作中检索所有页面后才能填充。如果省略，将返回*基本* 表中的结果，否则将返回*增量* 表中的结果。

**`basePartitionKey`**  
执行 `Sync` 操作时使用的*基* 表的分区键。在表使用自定义分区键时，该字段允许执行 `Sync` 操作。此为可选字段。

**`deltaIndexName`**  
用于 `Sync` 操作的索引。在表使用自定义分区键时，需要使用该索引才能对整个增量存储表启用 `Sync` 操作。`Sync` 操作是对 GSI（在 `gsi_ds_pk` 和 `gsi_ds_sk` 上创建）执行的。该字段是可选的。

DynamoDB 同步返回的结果自动转换为 GraphQL 和 JSON 基元类型，并在上下文结果 (`context.result`) 中提供。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

有关 JavaScript 解析器的更多信息，请参阅解析[JavaScript 器](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)概述。

结果的结构如下所示：

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10,
    startedAt = 1550000000000
}
```

字段定义如下：

** `items` **  
包含同步操作返回的项目的列表。

** `nextToken` **  
如果可能有更多结果，则`nextToken`包含可在其他请求中使用的分页令牌。 AWS AppSync 加密并混淆从 DynamoDB 返回的分页令牌。这可防止您的表数据无意中泄露给调用方。此外，这些分页标记不能在不同的函数或解析器中使用。

** `scannedCount` **  
在应用筛选条件表达式（如果有）之前 DynamoDB 检索的项目数。

** `startedAt` **  
同步操作开始的时刻，以纪元毫秒为单位，您可以在本地存储该值并在其他请求中将其用作 `lastSync` 参数。如果请求中包含分页令牌，则该值将与请求针对第一页结果返回的值相同。

## 示例
<a name="js-id14"></a>

以下示例是 GraphQL 查询 `syncPosts(nextToken: String, lastSync: AWSTimestamp)` 的函数请求处理程序。

在此示例中，如果省略 `lastSync`，则返回基表中的所有条目。如果提供了 `lastSync`，则只返回增量同步表中自 `lastSync` 以来发生更改的条目。

```
export function request(ctx) {
  const { nextToken, lastSync } = ctx.args;
  return { operation: 'Sync', limit: 100, nextToken, lastSync };
}
```

# BatchGetItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-get-item"></a>

`BatchGetItem`请求对象允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出`BatchGetItem`请求，以检索多个项目，可能跨多个表。对于该请求对象，您必须指定以下内容：
+ 要从中检索项目的表名称
+ 要从每个表中检索的项目的键

DynamoDB `BatchGetItem` 限制适用，并且无法提供**任何条件表达式**。

`BatchGetItem` 请求对象具有以下结构：

```
type DynamoDBBatchGetItemRequest = {
  operation: 'BatchGetItem';
  tables: {
    [tableName: string]: {
      keys: { [key: string]: any }[];
      consistentRead?: boolean; 
      projection?: {
        expression: string;
        expressionNames?: { [key: string]: string };
      };
    };
  };
};
```

字段定义如下：

## BatchGetItem 字段
<a name="js-BatchGetItem-list"></a>

### BatchGetItem 字段列表
<a name="js-BatchGetItem-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `BatchGetItem` DynamoDB 操作，该字段必须设置为 `BatchGetItem`。该值为必填项。

** `tables` **  
要从中检索项目的 DynamoDB 表。该值是一个映射，其中表名称被指定为映射的键。必须提供至少一个表。该 `tables` 值为必填项。    
** `keys` **  
DynamoDB 键列表，表示要检索的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。  
** `consistentRead` **  
执行*GetItem*操作时是否使用一致性读取。此值是可选的，默认为 *false*。  
**`projection`**  
用于指定从 DynamoDB 操作返回的属性的投影。有关投影的更多信息，请参阅[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。该字段是可选的。

要记住的事项：
+ 如果尚未从表中检索某个项目，则 *null* 元素将显示在该表的数据块中。
+ 根据在请求对象中提供调用结果的顺序，将按表对这些结果进行排序。
+ `BatchGetItem` 中的每个 `Get` 命令都是原子性的，但可以部分处理一个批次。如果由于错误而部分处理一个批处理，则未处理的键将作为 *unprocessedKeys* 块内的调用结果的一部分返回。
+  `BatchGetItem` 限制为 100 个键。

对于以下示例函数请求处理程序：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'BatchGetItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId })],
      posts: [util.dynamodb.toMapValues({ authorId, postId })],
    },
  };
}
```

`ctx.result` 中可用的调用结果如下所示：

```
{
   "data": {
     "authors": [null],
     "posts": [
        // Was retrieved
        {
          "authorId": "a1",
          "postId": "p2",
          "postTitle": "title",
          "postDescription": "description",
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        // This item was not processed due to an error
        {
          "authorId": "a1"
        }
      ],
     "posts": []
   }
}
```

`ctx.error` 包含有关该错误的详细信息。在调用结果中，确保会出现 **data** 和 **unprocessedKeys** 键以及在函数请求对象结果中提供的每个表键。已删除的项目显示在**数据**块中。尚未处理的项目将在数据块中标记为 *null* 并置于 **unprocessedKeys** 块中。

# BatchDeleteItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-delete-item"></a>

`BatchDeleteItem`请求对象允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB `BatchWriteItem` 请求删除多个项目，可能跨多个表。对于该请求对象，您必须指定以下内容：
+ 要从中删除项目的表名称
+ 要从每个表中删除的项目的键

DynamoDB `BatchWriteItem` 限制适用，并且无法提供**任何条件表达式**。

`BatchDeleteItem` 请求对象具有以下结构：

```
type DynamoDBBatchDeleteItemRequest = {
  operation: 'BatchDeleteItem';
  tables: {
    [tableName: string]: { [key: string]: any }[];
  };
};
```

字段定义如下：

## BatchDeleteItem 字段
<a name="js-BatchDeleteItem-list"></a>

### BatchDeleteItem 字段列表
<a name="js-BatchDeleteItem-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `BatchDeleteItem` DynamoDB 操作，该字段必须设置为 `BatchDeleteItem`。该值为必填项。

** `tables` **  
要从中删除项目的 DynamoDB 表。每个表是 DynamoDB 键列表，表示要删除的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。必须提供至少一个表。`tables` 值是必需的。

要记住的事项：
+ 与 `DeleteItem` 操作相反，响应中不会返回完全删除的项目。只返回传递的键。
+ 如果尚未从表中删除某个项目，*null* 元素将显示在该表的数据块中。
+ 根据在请求对象中提供调用结果的顺序，将按表对这些结果进行排序。
+ `BatchDeleteItem` 中的每个 `Delete` 命令都是原子性的。但是，可以部分处理一个批处理。如果由于错误而部分处理一个批处理，则未处理的键将作为 *unprocessedKeys* 块内的调用结果的一部分返回。
+  `BatchDeleteItem` 限制为 25 个键。
+ **不**支持与冲突检测功能一起使用此操作。两者同时使用可能会导致错误。

对于以下示例函数请求处理程序：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'BatchDeleteItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId })],
      posts: [util.dynamodb.toMapValues({ authorId, postId })],
    },
  };
}
```

`ctx.result` 中可用的调用结果如下所示：

```
{
   "data": {
     "authors": [null],
     "posts": [
        // Was deleted
        {
          "authorId": "a1",
          "postId": "p2"
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        // This key was not processed due to an error
        {
          "authorId": "a1"
        }
      ],
     "posts": []
   }
}
```

`ctx.error` 包含有关该错误的详细信息。在调用结果中，确保会出现 **data** 和 **unprocessedKeys** 键以及在函数请求对象中提供的每个表键。已删除的项目存在于**数据**块中。尚未处理的项目将在数据块中标记为 *null* 并置于 **unprocessedKeys** 块中。

# BatchPutItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-put-item"></a>

`BatchPutItem`请求对象允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出`BatchWriteItem`请求，要求将多个项目放置在多个表中。对于该请求对象，您必须指定以下内容：
+ 要将项目放置在其中的表名称
+ 要放置在每个表中的完整项目

DynamoDB `BatchWriteItem` 限制适用，并且无法提供**任何条件表达式**。

`BatchPutItem` 请求对象具有以下结构：

```
type DynamoDBBatchPutItemRequest = {
  operation: 'BatchPutItem';
  tables: {
    [tableName: string]: { [key: string]: any}[];
  };
};
```

字段定义如下：

## BatchPutItem 字段
<a name="js-BatchPutItem-list"></a>

### BatchPutItem 字段列表
<a name="js-BatchPutItem-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `BatchPutItem` DynamoDB 操作，该字段必须设置为 `BatchPutItem`。该值为必填项。

** `tables` **  
要在其中放置项目的 DynamoDB 表。每个表条目表示要为该特定表插入的 DynamoDB 项目列表。必须提供至少一个表。该值为必填项。

要记住的事项：
+ 如果成功，响应中将返回完全插入的项目。
+ 如果尚未向表中插入项目，*null* 元素将显示在该表的数据块中。
+ 根据在请求对象中提供插入的项目的顺序，将按表对这些结果进行排序。
+ `BatchPutItem` 中的每个 `Put` 命令都是原子性的，但可以部分处理一个批次。如果由于错误而部分处理一个批处理，则未处理的键将作为 *unprocessedKeys* 块内的调用结果的一部分返回。
+  `BatchPutItem` 限制为 25 个项目。
+ **不**支持与冲突检测功能一起使用此操作。两者同时使用可能会导致错误。

对于以下示例函数请求处理程序：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId, name, title } = ctx.args;
  return {
    operation: 'BatchPutItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId, name })],
      posts: [util.dynamodb.toMapValues({ authorId, postId, title })],
    },
  };
}
```

`ctx.result` 中可用的调用结果如下所示：

```
{
   "data": {
     "authors": [
         null
     ],
     "posts": [
        // Was inserted
        {
          "authorId": "a1",
          "postId": "p2",
          "title": "title"
        }
     ]
   },
   "unprocessedItems": {
     "authors": [
        // This item was not processed due to an error
        {
          "authorId": "a1",
          "name": "a1_name"
        }
      ],
     "posts": []
   }
}
```

`ctx.error` 包含有关该错误的详细信息。在调用结果中，确保会出现 **data** 和 **unprocessedItems** 键以及在请求对象中提供的每个表键。已插入的项目存在于**数据**块中。尚未处理的项目将在数据块中标记为 *null* 并置于 **unprocessedItems** 块中。

# TransactGetItems
<a name="js-aws-appsync-resolver-reference-dynamodb-transact-get-items"></a>

`TransactGetItems`请求对象允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出`TransactGetItems`请求，以检索多个项目，可能跨多个表。对于该请求对象，您必须指定以下内容：
+ 从中检索项目的每个请求项目的表名称
+ 要从每个表中检索的每个请求项的键

DynamoDB `TransactGetItems` 限制适用，并且无法提供**任何条件表达式**。

`TransactGetItems` 请求对象具有以下结构：

```
type DynamoDBTransactGetItemsRequest = {
  operation: 'TransactGetItems';
  transactItems: { table: string; key: { [key: string]: any }; projection?: { expression: string; expressionNames?: { [key: string]: string }; }[];
  };
};
```

字段定义如下：

## TransactGetItems 字段
<a name="js-TransactGetItems-list"></a>

### TransactGetItems 字段列表
<a name="js-TransactGetItems-list-col"></a>

** `operation` **  
要执行的 DynamoDB 操作。要执行 `TransactGetItems` DynamoDB 操作，该字段必须设置为 `TransactGetItems`。该值为必填项。

** `transactItems` **  
要包含的请求项目。该值是请求项目的数组。必须提供至少一个请求项目。该 `transactItems` 值为必填项。    
** `table` **  
要从中检索项目的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `key` **  
DynamoDB 键，表示要检索的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。  
**`projection`**  
用于指定从 DynamoDB 操作返回的属性的投影。有关投影的更多信息，请参阅[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。该字段是可选的。

要记住的事项：
+ 如果事务成功，`items` 块中检索项目的顺序将与请求项目的顺序相同。
+ 交易以 all-or-nothing某种方式执行。如果任何请求项目导致错误，则整个交易都不会执行，并返回错误详细信息。
+ 无法检索的请求项目不是错误。相反，*null* 元素会出现在相应位置的 *items* 块中。
+ 如果交易的错误是 *TransactionCanceledException*，则`cancellationReasons`区块将被填充。`cancellationReasons` 块中取消原因的顺序将与请求项目的顺序相同。
+  `TransactGetItems` 限制为 100 个请求项目。

对于以下示例函数请求处理程序：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'TransactGetItems',
    transactItems: [
      {
        table: 'posts',
        key: util.dynamodb.toMapValues({ postId }),
      },
      {
        table: 'authors',
        key: util.dynamodb.toMapValues({ authorId }),
      },
    ],
  };
}
```

如果事务成功并且只检索第一个请求的项目，则 `ctx.result` 中可用的调用结果如下所示：

```
{
    "items": [
       {
           // Attributes of the first requested item
           "post_id": "p1",
           "post_title": "title",
           "post_description": "description"
       },
       // Could not retrieve the second requested item
       null,
    ],
    "cancellationReasons": null
}
```

如果由于第一个请求项*TransactionCanceledException*导致事务失败，则中可用的调用结果如下`ctx.result`所示：

```
{
    "items": null,
    "cancellationReasons": [
       {
           "type":"Sample error type",
           "message":"Sample error message"
       },
       {
           "type":"None",
           "message":"None"
       }
    ]
}
```

`ctx.error` 包含有关该错误的详细信息。键 **items** 和 **cancellationReasons** 保证出现在 `ctx.result` 中。

# TransactWriteItems
<a name="js-aws-appsync-resolver-reference-dynamodb-transact-write-items"></a>

`TransactWriteItems`请求对象允许您告诉 D AWS AppSync ynamoDB 函数向 DynamoDB 发出写入多个项目（可能写入多个表）的`TransactWriteItems`请求。对于该请求对象，您必须指定以下内容：
+ 每个请求项目的目标表名称
+ 要执行的每个请求项目的操作。支持四种类型的操作：*PutItem*、*UpdateItem*DeleteItem**、和 *ConditionCheck* 
+ 要写入的每个请求项目的键

DynamoDB `TransactWriteItems` 限制适用。

`TransactWriteItems` 请求对象具有以下结构：

```
type DynamoDBTransactWriteItemsRequest = {
  operation: 'TransactWriteItems';
  transactItems: TransactItem[];
};
type TransactItem =
  | TransactWritePutItem
  | TransactWriteUpdateItem
  | TransactWriteDeleteItem
  | TransactWriteConditionCheckItem;
type TransactWritePutItem = {
  table: string;
  operation: 'PutItem';
  key: { [key: string]: any };
  attributeValues: { [key: string]: string};
  condition?: TransactConditionCheckExpression;
};
type TransactWriteUpdateItem = {
  table: string;
  operation: 'UpdateItem';
  key: { [key: string]: any };
  update: DynamoDBExpression;
  condition?: TransactConditionCheckExpression;
};
type TransactWriteDeleteItem = {
  table: string;
  operation: 'DeleteItem';
  key: { [key: string]: any };
  condition?: TransactConditionCheckExpression;
};
type TransactWriteConditionCheckItem = {
  table: string;
  operation: 'ConditionCheck';
  key: { [key: string]: any };
  condition?: TransactConditionCheckExpression;
};
type TransactConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
  returnValuesOnConditionCheckFailure: boolean;
};
```

## TransactWriteItems 字段
<a name="js-TransactWriteItems-list"></a>

### TransactWriteItems 字段列表
<a name="js-TransactWriteItems-list-col"></a>

**字段定义如下：**    
** `operation` **  
要执行的 DynamoDB 操作。要执行 `TransactWriteItems` DynamoDB 操作，该字段必须设置为 `TransactWriteItems`。该值为必填项。  
** `transactItems` **  
要包含的请求项目。该值是请求项目的数组。必须提供至少一个请求项目。该 `transactItems` 值为必填项。  
对于 `PutItem`，字段定义如下：    
** `table` **  
目标 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `PutItem` DynamoDB 操作，该字段必须设置为 `PutItem`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要放置的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。  
** `attributeValues` **  
要放入 DynamoDB 中的项目的其余属性。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该字段是可选的。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `PutItem` 请求将覆盖该项目的任何现有条目。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。该值为可选项。
对于 `UpdateItem`，字段定义如下：    
** `table` **  
要更新的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `UpdateItem` DynamoDB 操作，该字段必须设置为 `UpdateItem`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要更新的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。  
** `update` **  
`update` 部分用于指定一个更新表达式，以描述如何更新 DynamoDB 中的项目。有关如何编写更新表达式的更多信息，请参阅 [DynamoDB 文档 UpdateExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)。此部分是必需的。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `UpdateItem` 请求将更新现有条目，而不考虑其当前状态。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。该值为可选项。
对于 `DeleteItem`，字段定义如下：    
** `table` **  
要在其中删除项目的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `DeleteItem` DynamoDB 操作，该字段必须设置为 `DeleteItem`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要删除的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `DeleteItem` 请求将删除项目，而不考虑其当前状态。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。该值为可选项。
对于 `ConditionCheck`，字段定义如下：    
** `table` **  
要在其中检查条件的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `ConditionCheck` DynamoDB 操作，该字段必须设置为 `ConditionCheck`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要检查条件的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。该值为必填项。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。该值为必填项。

要记住的事项：
+ 如果成功，响应中只返回请求项目的键。键的顺序将与请求项目的顺序相同。
+ 交易以 all-or-nothing某种方式执行。如果任何请求项目导致错误，则整个交易都不会执行，并返回错误详细信息。
+ 不能有两个请求项目针对同一个项目。否则它们会导致*TransactionCanceledException*错误。
+ 如果交易的错误是 *TransactionCanceledException*，则`cancellationReasons`区块将被填充。如果请求项目的条件检查失败**且** 您没有将 `returnValuesOnConditionCheckFailure` 指定为 `false`，则表中存在的项目将被检索并存储在 `cancellationReasons` 块的相应位置的 `item` 中。
+  `TransactWriteItems` 限制为 100 个请求项目。
+ **不**支持与冲突检测功能一起使用此操作。两者同时使用可能会导致错误。

对于以下示例函数请求处理程序：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId, title, description, oldTitle, authorName } = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'PutItem',
        key: util.dynamodb.toMapValues({ postId }),
        attributeValues: util.dynamodb.toMapValues({ title, description }),
        condition: util.transform.toDynamoDBConditionExpression({
          title: { eq: oldTitle },
        }),
      },
      {
        table: 'authors',
        operation: 'UpdateItem',
        key: util.dynamodb.toMapValues({ authorId }),
        update: {
          expression: 'SET authorName = :name',
          expressionValues: util.dynamodb.toMapValues({ ':name': authorName }),
        },
      },
    ],
  };
}
```

如果事务成功，`ctx.result` 中可用的调用结果如下所示：

```
{
    "keys": [
       // Key of the PutItem request
       {
           "post_id": "p1",
       },
       // Key of the UpdateItem request
       {
           "author_id": "a1"
       }
    ],
    "cancellationReasons": null
}
```

如果由于 `PutItem` 请求的条件检查失败而导致事务失败，则 `ctx.result` 中提供的调用结果如下所示：

```
{
    "keys": null,
    "cancellationReasons": [
       {
           "item": {
               "post_id": "p1",
               "post_title": "Actual old title",
               "post_description": "Old description"
           },
           "type": "ConditionCheckFailed",
           "message": "The condition check failed."
       },
       {
           "type": "None",
           "message": "None"
       }
    ]
}
```

`ctx.error` 包含有关该错误的详细信息。键 **keys** 和 **cancellationReasons** 保证出现在 `ctx.result` 中。

# 类型系统（请求映射）
<a name="js-aws-appsync-resolver-reference-dynamodb-typed-values-request"></a>

使用 D AWS AppSync ynamoDB 函数调用您的 DynamoDB 表时 AWS AppSync ，需要知道要在该调用中使用的每个值的类型。这是因为 DynamoDB 支持的类型基元比 GraphQL 或 JSON 多（例如集合和二进制数据）。 AWS AppSync 在 GraphQL 和 DynamoDB 之间进行转换时需要一些提示，否则它将不得不对表中的数据结构做出一些假设。

有关 DynamoDB 数据类型的更多信息，请参阅 DynamoDB [数据类型描述符](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html#Programming.LowLevelAPI.DataTypeDescriptors)和[数据类型](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes)文档。

DynamoDB 值由包含单个键值对的 JSON 对象表示。键指定 DynamoDB 类型，值指定值本身。在下面的示例中，键 `S` 表示值是一个字符串，值 `identifier` 是字符串值本身。

```
{ "S" : "identifier" }
```

请注意，JSON 对象不能具有多于一个键值对。如果指定了多个键值对，则不会解析请求对象。

DynamoDB 值用于请求对象中您需要指定值的任何位置。您需要这样做的一些地方包括：`key` 和 `attributeValue` 部分以及表达式部分的 `expressionValues` 部分。在以下示例中，DynamoDB 字符串值 `identifier` 分配给 `key` 部分中的 `id` 字段（可能位于 `GetItem` 请求对象中）。

```
"key" : {
   "id" : { "S" : "identifier" }
}
```

 **支持的类型** 

AWS AppSync 支持以下 DynamoDB 标量、文档和集合类型：

**字符串类型 `S` **  
单个字符串值。DynamoDB 字符串值表示为：  

```
{ "S" : "some string" }
```
示例用法如下：  

```
"key" : {
   "id" : { "S" : "some string" }
}
```

**字符串集类型 `SS` **  
一组字符串值。DynamoDB 字符串集值表示为：  

```
{ "SS" : [ "first value", "second value", ... ] }
```
示例用法如下：  

```
"attributeValues" : {
   "phoneNumbers" : { "SS" : [ "+1 555 123 4567", "+1 555 234 5678" ] }
}
```

**数字类型 `N` **  
单个数字值。DynamoDB 数字值表示为：  

```
{ "N" : 1234 }
```
示例用法如下：  

```
"expressionValues" : {
   ":expectedVersion" : { "N" : 1 }
}
```

**数字集类型 `NS` **  
一组数字值。DynamoDB 数字集值表示为：  

```
{ "NS" : [ 1, 2.3, 4 ... ] }
```
示例用法如下：  

```
"attributeValues" : {
   "sensorReadings" : { "NS" : [ 67.8, 12.2, 70 ] }
}
```

**二进制类型 `B` **  
二进制值。DynamoDB 二进制值表示为：  

```
{ "B" : "SGVsbG8sIFdvcmxkIQo=" }
```
请注意，该值实际上是一个字符串，其中字符串是二进制数据的 base64 编码表示形式。 AWS AppSync 将此字符串解码回其二进制值，然后再将其发送到 DynamoDB。 AWS AppSync 使用 RFC 2045 中定义的 base64 解码方案：任何不在 base64 字母表中的字符都将被忽略。  
示例用法如下：  

```
"attributeValues" : {
   "binaryMessage" : { "B" : "SGVsbG8sIFdvcmxkIQo=" }
}
```

**二进制集类型 `BS` **  
一组二进制值。DynamoDB 二进制集值表示为：  

```
{ "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ] }
```
请注意，该值实际上是一个字符串，其中字符串是二进制数据的 base64 编码表示形式。 AWS AppSync 将此字符串解码回其二进制值，然后再将其发送到 DynamoDB。 AWS AppSync 使用 RFC 2045 中定义的 base64 解码方案：任何不在 base64 字母表中的字符都将被忽略。  
示例用法如下：  

```
"attributeValues" : {
   "binaryMessages" : { "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ] }
}
```

**布尔值类型 `BOOL` **  
布尔值。DynamoDB 布尔值表示为：  

```
{ "BOOL" : true }
```
请注意，只有 `true` 和 `false` 是有效值。  
示例用法如下：  

```
"attributeValues" : {
   "orderComplete" : { "BOOL" : false }
}
```

**列表类型 `L` **  
任何其他支持的 DynamoDB 值列表。DynamoDB 列表值表示为：  

```
{ "L" : [ ... ] }
```
请注意，该值是一个复合值，其中，列表可以包含零个或更多任何支持的 DynamoDB 值（包括其他列表）。此列表还可以包含不同类型的混合。  
示例用法如下：  

```
{ "L" : [
      { "S"  : "A string value" },
      { "N"  : 1 },
      { "SS" : [ "Another string value", "Even more string values!" ] }
   ]
}
```

**映射类型 `M` **  
表示其他支持的 DynamoDB 值的键值对的无序集合。DynamoDB 映射值表示为：  

```
{ "M" : { ... } }
```
请注意，一个映射可以包含零个或零个以上的键值对。键必须是一个字符串，值可以是任何支持的 DynamoDB 值（包括其他映射）。此映射还可以包含不同类型的混合。  
示例用法如下：  

```
{ "M" : {
      "someString" : { "S"  : "A string value" },
      "someNumber" : { "N"  : 1 },
      "stringSet"  : { "SS" : [ "Another string value", "Even more string values!" ] }
   }
}
```

**Null 类型 `NULL` **  
Null 值。DynamoDB Null 值表示为：  

```
{ "NULL" : null }
```
示例用法如下：  

```
"attributeValues" : {
   "phoneNumbers" : { "NULL" : null }
}
```

有关每个类型的更多信息，请参阅 [DynamoDB 文档](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html)。

# 类型系统（响应映射）
<a name="js-aws-appsync-resolver-reference-dynamodb-typed-values-responses"></a>

收到来自 DynamoDB 的响应时 AWS AppSync ，会自动将其转换为 GraphQL 和 JSON 原始类型。将解码 DynamoDB 中的每个属性，并在响应处理程序的上下文中返回。

例如，如果 DynamoDB 返回以下内容：

```
{
    "id" : { "S" : "1234" },
    "name" : { "S" : "Nadia" },
    "age" : { "N" : 25 }
}
```

当管道解析器返回结果时，将其 AWS AppSync 转换为 GraphQL 和 JSON 类型，如下所示：

```
{
    "id" : "1234",
    "name" : "Nadia",
    "age" : 25
}
```

本节介绍如何 AWS AppSync 转换以下 DynamoDB 标量、文档和集合类型：

**字符串类型 `S` **  
单个字符串值。DynamoDB 字符串值以字符串形式返回。  
例如，如果 DynamoDB 返回以下 DynamoDB 字符串值：  

```
{ "S" : "some string" }
```
AWS AppSync 将其转换为字符串：  

```
"some string"
```

**字符串集类型 `SS` **  
一组字符串值。DynamoDB 字符串集值以字符串列表形式返回。  
例如，如果 DynamoDB 返回以下 DynamoDB 字符串集值：  

```
{ "SS" : [ "first value", "second value", ... ] }
```
AWS AppSync 将其转换为字符串列表：  

```
[ "+1 555 123 4567", "+1 555 234 5678" ]
```

**数字类型 `N` **  
单个数字值。DynamoDB 数字值以数字形式返回。  
例如，如果 DynamoDB 返回以下 DynamoDB 数字值：  

```
{ "N" : 1234 }
```
AWS AppSync 将其转换为数字：  

```
1234
```

**数字集类型 `NS` **  
一组数字值。DynamoDB 数字集值以数字列表形式返回。  
例如，如果 DynamoDB 返回以下 DynamoDB 数字集值：  

```
{ "NS" : [ 67.8, 12.2, 70 ] }
```
AWS AppSync 将其转换为数字列表：  

```
[ 67.8, 12.2, 70 ]
```

**二进制类型 `B` **  
二进制值。DynamoDB 二进制值以字符串形式返回，其中包含该值的 Base64 表示形式。  
例如，如果 DynamoDB 返回以下 DynamoDB 二进制值：  

```
{ "B" : "SGVsbG8sIFdvcmxkIQo=" }
```
AWS AppSync 将其转换为包含该值的 base64 表示形式的字符串：  

```
"SGVsbG8sIFdvcmxkIQo="
```
请注意，二进制数据按照 [RFC 4648](https://tools.ietf.org/html/rfc4648) 和 [RFC 2045](https://tools.ietf.org/html/rfc2045) 中指定的方式根据 base64 编码方案进行编码。

**二进制集类型 `BS` **  
一组二进制值。DynamoDB 二进制集值以字符串列表形式返回，其中包含这些值的 Base64 表示形式。  
例如，如果 DynamoDB 返回以下 DynamoDB 二进制集值：  

```
{ "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ] }
```
AWS AppSync 将其转换为包含以下值的 base64 表示形式的字符串列表：  

```
[ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ]
```
请注意，二进制数据按照 [RFC 4648](https://tools.ietf.org/html/rfc4648) 和 [RFC 2045](https://tools.ietf.org/html/rfc2045) 中指定的方式根据 base64 编码方案进行编码。

**布尔值类型 `BOOL` **  
布尔值。DynamoDB 布尔值以布尔值形式返回。  
例如，如果 DynamoDB 返回以下 DynamoDB 布尔值：  

```
{ "BOOL" : true }
```
AWS AppSync 将其转换为布尔值：  

```
true
```

**列表类型 `L` **  
任何其他支持的 DynamoDB 值列表。DynamoDB 列表值以值列表形式返回，其中还会转换每个内部值。  
例如，如果 DynamoDB 返回以下 DynamoDB 列表值：  

```
{ "L" : [
      { "S"  : "A string value" },
      { "N"  : 1 },
      { "SS" : [ "Another string value", "Even more string values!" ] }
   ]
}
```
AWS AppSync 将其转换为转换后的值列表：  

```
[ "A string value", 1, [ "Another string value", "Even more string values!" ] ]
```

**映射类型 `M` **  
任何其他受支持的 DynamoDB 值的 key/value 集合。DynamoDB 地图值以 JSON 对象的形式返回， key/value 每个值也将在其中进行转换。  
例如，如果 DynamoDB 返回以下 DynamoDB 映射值：  

```
{ "M" : {
      "someString" : { "S"  : "A string value" },
      "someNumber" : { "N"  : 1 },
      "stringSet"  : { "SS" : [ "Another string value", "Even more string values!" ] }
   }
}
```
AWS AppSync 将其转换为 JSON 对象：  

```
{
   "someString" : "A string value",
   "someNumber" : 1,
   "stringSet"  : [ "Another string value", "Even more string values!" ]
}
```

**Null 类型 `NULL` **  
Null 值。  
例如，如果 DynamoDB 返回以下 DynamoDB Null 值：  

```
{ "NULL" : null }
```
AWS AppSync 将其转换为空值：  

```
null
```

# 筛选条件
<a name="js-aws-appsync-resolver-reference-dynamodb-filter"></a>

在使用 `Query` 和 `Scan` 操作查询 DynamoDB 中的对象时，您可以选择指定 `filter` 以评估结果并仅返回所需的值。

`Query` 或 `Scan` 请求的 filter 属性具有以下结构：

```
type DynamoDBExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
};
```

字段定义如下：

** `expression` **  
查询表达式。有关如何编写筛选表达式的更多信息，请参阅 [DynamoDB 和 Dynam QueryFilter oDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.QueryFilter.html) 文档[。 ScanFilter](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ScanFilter.html)必须指定该字段。

** `expressionNames` **  
以键值对形式替换表达式属性*名称* 占位符。键对应于 `expression` 中使用的名称占位符。该值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 `expression` 中使用的表达式属性名称占位符的替换内容。

** `expressionValues` **  
以键值对形式替换表达式属性*值* 占位符。键对应于 `expression` 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。必须指定此值。该字段是可选的，只应填充 `expression` 中使用的表达式属性值占位符的替换内容。

## 示例
<a name="js-id18"></a>

以下示例是请求的筛选条件部分，其中，只有在标题以 `title` 参数开头时，才会返回从 DynamoDB 中检索的条目。

此处，我们使用 `util.transform.toDynamoDBFilterExpression` 从对象中自动创建筛选条件：

```
const filter = util.transform.toDynamoDBFilterExpression({
  title: { beginsWith: 'far away' },
});

const request = {};
request.filter = JSON.parse(filter);
```

这会生成以下筛选条件：

```
{
  "filter": {
    "expression": "(begins_with(#title,:title_beginsWith))",
    "expressionNames": { "#title": "title" },
    "expressionValues": {
      ":title_beginsWith": { "S": "far away" }
    }
  }
}
```

# 条件表达式
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-expressions"></a>

在您使用 `PutItem`、`UpdateItem` 和 `DeleteItem` DynamoDB 操作变更 DynamoDB 中的对象时，您可以选择指定一个条件表达式，以根据执行操作之前 DynamoDB 中的已有对象状态控制请求是否应成功。

D AWS AppSync ynamoDB 函数允许`PutItem`在`UpdateItem`、`DeleteItem`和请求对象中指定条件表达式，还允许在条件失败且对象未更新时遵循的策略。

## 示例 1
<a name="js-id19"></a>

以下 `PutItem` 请求对象没有条件表达式。因此，即使已存在具有相同键的项目，它也会将项目放置在 DynamoDB 中，从而覆盖现有的项目。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

## 示例 2
<a name="js-id20"></a>

以下 `PutItem` 对象确实具有一个条件表达式，只有在 DynamoDB 中*不* 存在具有相同键的项目时，该操作才会成功。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
    condition: { expression: "attribute_not_exists(id)" }
  };
}
```

默认情况下，如果条件检查失败，则 AWS AppSync DynamoDB 函数会为突变提供错误。

但是， AWS AppSync DynamoDB 函数提供了一些其他功能来帮助开发人员处理一些常见的边缘情况：
+ 如果 D AWS AppSync ynamoDB 函数可以确定 DynamoDB 中的当前值与所需结果相匹配，则它会将该操作视为成功了。
+ 您可以将函数配置为调用自定义 Lambda 函数来决定 DynamoDB 函数应如何处理故障 AWS AppSync ，而不是返回错误。

在[处理条件检查失败](#condition-check)一节中更详细地介绍了这些内容。

[有关 DynamoDB 条件表达式的更多信息，请参阅 DynamoDB 文档。 ConditionExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)

## 指定条件
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-specification"></a>

`PutItem`、`UpdateItem` 和 `DeleteItem` 请求对象都允许指定可选的 `condition` 部分。如果省略，则不会进行条件检查。如果指定，条件必须为 true，操作才能成功。

`condition` 部分具有以下结构：

```
type ConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
  equalsIgnore?: string[];
  consistentRead?: boolean;
  conditionalCheckFailedHandler?: {
    strategy: 'Custom' | 'Reject';
    lambdaArn?: string;
  };
};
```

下列字段指定条件：

** `expression` **  
更新表达式本身。有关如何编写条件表达式的更多信息，请参阅 [DynamoDB 文档 ConditionExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)。必须指定该字段。

** `expressionNames` **  
以键值对形式替换表达式属性名称占位符。键对应于 *expression* 中使用的名称占位符，值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 *expression* 中使用的表达式属性名称占位符的替换内容。

** `expressionValues` **  
以键值对形式替换表达式属性值占位符。键对应于 expression 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。必须指定此值。该字段是可选的，只应填充 expression 中使用的表达式属性值占位符的替换内容。

其余字段告诉 AWS AppSync DynamoDB 函数如何处理条件检查失败：

** `equalsIgnore` **  
当使用`PutItem`操作时条件检查失败时，D AWS AppSync ynamoDB 函数会将当前在 DynamoDB 中的项目与它尝试写入的项目进行比较。如果两者相同，则它会将操作视为已成功。您可以使用该`equalsIgnore`字段来指定在执行比较时 AWS AppSync 应忽略的属性列表。例如，如果唯一的区别是 `version` 属性，则会将操作视为成功。该字段是可选的。

** `consistentRead` **  
当条件检查失败时，使用强一致性读取从 DynamoDB AWS AppSync 获取项目的当前值。您可以使用此字段告诉 AWS AppSync DynamoDB 函数改用最终一致性读取。该字段是可选的，默认值为 `true`。

** `conditionalCheckFailedHandler` **  
本节允许您指定 D AWS AppSync ynamoDB 函数在将 DynamoDB 中的当前值与预期结果进行比较后如何处理条件检查失败。此部分是可选的。如果省略，它默认为 `Reject` 策略。    
** `strategy` **  
 AWS AppSync DynamoDB 函数在将 DynamoDB 中的当前值与预期结果进行比较后采取的策略。该字段为必填字段，有以下可能的值：    
** `Reject` **  
变更失败，向 GraphQL 响应中添加一个错误。  
** `Custom` **  
 AWS AppSync DynamoDB 函数调用自定义 Lambda 函数来决定如何处理条件检查失败。当 `strategy` 设置为 `Custom` 时，`lambdaArn` 字段必须包含要调用的 Lambda 函数的 ARN。  
** `lambdaArn` **  
要调用的 Lambda 函数的 ARN，用于确定 DynamoDB 函数应如何处理条件 AWS AppSync 检查失败。当 `strategy` 设置为 `Custom` 时，必须指定该字段。有关如何使用该功能的更多信息，请参阅[处理条件检查失败](#condition-check)。

## 处理条件检查失败
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-handling"></a>

当条件检查失败时，D AWS AppSync ynamoDB 函数可以使用该实用程序传递突变的错误和对象的当前值。`util.appendError`但是， AWS AppSync DynamoDB 函数提供了一些其他功能来帮助开发人员处理一些常见的边缘情况：
+ 如果 D AWS AppSync ynamoDB 函数可以确定 DynamoDB 中的当前值与所需结果相匹配，则它会将该操作视为成功了。
+ 您可以将函数配置为调用自定义 Lambda 函数来决定 DynamoDB 函数应如何处理故障 AWS AppSync ，而不是返回错误。

此过程的流程图为：

![\[Flowchart showing process for transforming requests with mutation attempts and value checks.\]](http://docs.aws.amazon.com/zh_cn/appsync/latest/devguide/images/DynamoDB-condition-check-failure-handling.png)


### 检查所需的结果
<a name="js-checking-for-the-desired-result"></a>

当条件检查失败时，D AWS AppSync ynamoDB 函数会执行 Dyn `GetItem` amoDB 请求，以从 DynamoDB 获取项目的当前值。默认情况下，它将使用强一致性读取，但这可以使用 `condition` 数据块中的 `consistentRead` 字段进行配置，并将当前值与预期结果进行比较：
+ 对于该`PutItem`操作，D AWS AppSync ynamoDB 函数将当前值与其尝试写入的值进行比较，不包括比较`equalsIgnore`中列出的任何属性。如果项目相同，则将操作视为成功并返回从 DynamoDB 中检索的项目。否则，它将遵循所配置的策略。

  例如，如果 `PutItem` 请求对象如下所示：

  ```
  import { util } from '@aws-appsync/utils';
  export function request(ctx) {
    const { id, name, version} = ctx.args
    return {
      operation: 'PutItem',
      key: util.dynamodb.toMapValues({foo, bar}),
      attributeValues: util.dynamodb.toMapValues({ name, version: version+1 }),
      condition: { 
        expression: "version = :expectedVersion",
        expressionValues: util.dynamodb.toMapValues({':expectedVersion': version}),
        equalsIgnore: ['version']
      }
    };
  }
  ```

  当前位于 DynamoDB 中的项目如下所示：

  ```
  {
     "id" : { "S" : "1" },
     "name" : { "S" : "Steve" },
     "version" : { "N" : 8 }
  }
  ```

  D AWS AppSync ynamoDB 函数会将其尝试写入的项目与当前值进行比较，发现唯一的区别在于字段，但是由于它配置为忽略`version``version`该字段，因此它会将操作视为成功并返回从 DynamoDB 检索到的项目。
+ 对于该`DeleteItem`操作， AWS AppSync DynamoDB 函数会进行检查以验证是否从 DynamoDB 返回了项目。如果没有返回项目，它会将该操作视为已成功。否则，它将遵循所配置的策略。
+ 对于该`UpdateItem`操作，D AWS AppSync ynamoDB 函数没有足够的信息来确定 DynamoDB 中当前的项目是否与预期结果匹配，因此遵循了配置的策略。

如果 DynamoDB 中对象的当前状态与预期结果不同，则 D AWS AppSync ynamoDB 函数将遵循配置的策略，拒绝变更或调用 Lambda 函数来确定下一步要做什么。

### 遵循“reject”策略
<a name="js-following-the-reject-strategy"></a>

遵循`Reject`策略时， AWS AppSync DynamoDB 函数会返回变异错误。

例如，给定以下变更请求：

```
mutation {
    updatePerson(id: 1, name: "Steve", expectedVersion: 1) {
        Name
        theVersion
    }
}
```

如果从 DynamoDB 返回的项目如下所示：

```
{
   "id" : { "S" : "1" },
   "name" : { "S" : "Steve" },
   "version" : { "N" : 8 }
}
```

函数响应处理程序如下所示：

```
import { util } from '@aws-appsync/utils';
export function response(ctx) {
  const { version, ...values } = ctx.result;
  const result = { ...values, theVersion: version };
  if (ctx.error) {
    if (error) {
      return util.appendError(error.message, error.type, result, null);
    }
  }
  return result
}
```

GraphQL 响应如下所示：

```
{
  "data": null,
  "errors": [
    {
      "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
      "errorType": "DynamoDB:ConditionalCheckFailedException",
      ...
    }
  ]
}
```

另外，如果返回的对象中的任何字段在变更成功后已由其他解析器填充，则当在 `error` 部分中返回此对象时，将不会对这些字段进行解析。

### 遵循“custom”策略
<a name="js-following-the-custom-strategy"></a>

遵循`Custom`策略时， AWS AppSync DynamoDB 函数会调用 Lambda 函数来决定下一步要做什么。Lambda 函数选择下列选项之一：
+  `reject` 变更。这告诉 D AWS AppSync ynamoDB 函数的行为就像配置的策略`Reject`一样，返回变异错误和 DynamoDB 中对象的当前值，如上一节所述。
+  `discard` 变更。这会告诉 AWS AppSync DynamoDB 函数以静默方式忽略条件检查失败，并在 DynamoDB 中返回该值。
+  `retry` 变更。这会告诉 AWS AppSync DynamoDB 函数使用新的请求对象重试变更。

 **Lambda 调用请求**

 AWS AppSync DynamoDB 函数调用中指定的 Lambda 函数。`lambdaArn`它将使用在数据来源上配置的相同 `service-role-arn`。调用的负载具有以下结构：

```
{
    "arguments": { ... },
    "requestMapping": {... },
    "currentValue": { ... },
    "resolver": { ... },
    "identity": { ... }
}
```

字段定义如下：

** `arguments` **  
来自 GraphQL 变更的参数。这与 `context.arguments` 中的请求对象的可用参数相同。

** `requestMapping` **  
该操作的请求对象。

** `currentValue` **  
DynamoDB 中的对象的当前值。

** `resolver` **  
有关 AWS AppSync 解析器或函数的信息。

** `identity` **  
有关调用方的信息。这与 `context.identity` 中的请求对象的可用身份信息相同。

负载的完整示例：

```
{
    "arguments": {
        "id": "1",
        "name": "Steve",
        "expectedVersion": 1
    },
    "requestMapping": {
        "version" : "2017-02-28",
        "operation" : "PutItem",
        "key" : {
           "id" : { "S" : "1" }
        },
        "attributeValues" : {
           "name" : { "S" : "Steve" },
           "version" : { "N" : 2 }
        },
        "condition" : {
           "expression" : "version = :expectedVersion",
           "expressionValues" : {
               ":expectedVersion" : { "N" : 1 }
           },
           "equalsIgnore": [ "version" ]
        }
    },
    "currentValue": {
        "id" : { "S" : "1" },
        "name" : { "S" : "Steve" },
        "version" : { "N" : 8 }
    },
    "resolver": {
        "tableName": "People",
        "awsRegion": "us-west-2",
        "parentType": "Mutation",
        "field": "updatePerson",
        "outputType": "Person"
    },
    "identity": {
        "accountId": "123456789012",
        "sourceIp": "x.x.x.x",
        "user": "AIDAAAAAAAAAAAAAAAAAA",
        "userArn": "arn:aws:iam::123456789012:user/appsync"
    }
}
```

 **Lambda 调用响应** 

Lambda 函数可以检查调用负载并应用任何业务逻辑来决定 DynamoDB 函数应如何处理 AWS AppSync 故障。有三种选项可用于处理条件检查失败：
+  `reject` 变更。此选项的响应负载必须具有此结构：

  ```
  {
      "action": "reject"
  }
  ```

  这告诉 D AWS AppSync ynamoDB 函数的行为就像配置的策略`Reject`一样，返回变异错误以及该对象在 DynamoDB 中的当前值，如上一节所述。
+  `discard` 变更。此选项的响应负载必须具有此结构：

  ```
  {
      "action": "discard"
  }
  ```

  这会告诉 AWS AppSync DynamoDB 函数以静默方式忽略条件检查失败，并在 DynamoDB 中返回该值。
+  `retry` 变更。此选项的响应负载必须具有此结构：

  ```
  {
      "action": "retry",
      "retryMapping": { ... }
  }
  ```

  这会告诉 AWS AppSync DynamoDB 函数使用新的请求对象重试变更。`retryMapping` 部分的结构取决于 DynamoDB 操作，并且是该操作的完整请求对象的子集。

  对于 `PutItem`，`retryMapping` 部分具有以下结构。有关该`attributeValues`字段的说明，请参见[PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-putitem)。

  ```
  {
      "attributeValues": { ... },
      "condition": {
          "equalsIgnore" = [ ... ],
          "consistentRead" = true
      }
  }
  ```

  对于 `UpdateItem`，`retryMapping` 部分具有以下结构。有关该`update`部分的说明，请参见[UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem)。

  ```
  {
      "update" : {
          "expression" : "someExpression"
          "expressionNames" : {
              "#foo" : "foo"
          },
          "expressionValues" : {
              ":bar" : ... typed value
          }
      },
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  对于 `DeleteItem`，`retryMapping` 部分具有以下结构。

  ```
  {
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  无法指定要使用的不同的操作或键。 AWS AppSync DynamoDB 函数仅允许对同一个对象重试相同的操作。另外，`condition` 部分不允许指定 `conditionalCheckFailedHandler`。如果重试失败，则 Dynamo AWS AppSync DB 函数将遵循策略。`Reject`

在下面的示例中，Lambda 函数处理失败的 `PutItem` 请求。业务逻辑将查看进行调用的用户。如果调用是由 `jeffTheAdmin` 进行的，则会重试该请求，并从当前位于 DynamoDB 的项目中更新 `version` 和 `expectedVersion`。否则，业务逻辑将拒绝变更。

```
exports.handler = (event, context, callback) => {
    console.log("Event: "+ JSON.stringify(event));

    // Business logic goes here.

    var response;
    if ( event.identity.user == "jeffTheAdmin" ) {
        response = {
            "action" : "retry",
            "retryMapping" : {
                "attributeValues" : event.requestMapping.attributeValues,
                "condition" : {
                    "expression" : event.requestMapping.condition.expression,
                    "expressionValues" : event.requestMapping.condition.expressionValues
                }
            }
        }
        response.retryMapping.attributeValues.version = { "N" : event.currentValue.version.N + 1 }
        response.retryMapping.condition.expressionValues[':expectedVersion'] = event.currentValue.version

    } else {
        response = { "action" : "reject" }
    }

    console.log("Response: "+ JSON.stringify(response))
    callback(null, response)
};
```

# 事务条件表达式
<a name="js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions"></a>

可以在 `TransactWriteItems` 中的所有 4 种类型的操作（`PutItem`、`DeleteItem`、`UpdateItem` 和 `ConditionCheck`）的请求中使用事务条件表达式。

对于 `PutItem`、`DeleteItem` 和 `UpdateItem`，事务条件表达式是可选的。对于 `ConditionCheck`，事务条件表达式是必需的。

## 示例 1
<a name="js-id22"></a>

以下事务 `DeleteItem` 函数请求处理程序没有条件表达式。因此，它删除 DynamoDB 中的项目。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { postId } = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'DeleteItem',
        key: util.dynamodb.toMapValues({ postId }),
      }
    ],
  };
}
```

## 示例 2
<a name="js-id23"></a>

以下事务 `DeleteItem` 函数请求处理程序确实具有一个事务条件表达式，只有在该文章的作者等于特定姓名时，操作才会成功。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { postId, authorName} = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'DeleteItem',
        key: util.dynamodb.toMapValues({ postId }),
        condition: util.transform.toDynamoDBConditionExpression({
          authorName: { eq: authorName },
        }),
      }
    ],
  };
}
```

如果条件检查失败，则会导致 `TransactionCanceledException`，错误详细信息将在 `ctx.result.cancellationReasons` 中返回。请注意，默认情况下，DynamoDB 中导致条件检查失败的旧项目将在 `ctx.result.cancellationReasons` 中返回。

## 指定条件
<a name="js-id24"></a>

`PutItem`、`UpdateItem` 和 `DeleteItem` 请求对象都允许指定可选的 `condition` 部分。如果省略，则不会进行条件检查。如果指定，条件必须为 true，操作才能成功。`ConditionCheck` 必须具有要指定的 `condition` 部分。条件必须为 true，整个事务才能成功。

`condition` 部分具有以下结构：

```
type TransactConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string };
  expressionValues?: { [key: string]: string };
  returnValuesOnConditionCheckFailure: boolean;
};
```

下列字段指定条件：

** `expression` **  
更新表达式本身。有关如何编写条件表达式的更多信息，请参阅 [DynamoDB 文档 ConditionExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)。必须指定该字段。

** `expressionNames` **  
以键值对形式替换表达式属性名称占位符。键对应于 *expression* 中使用的名称占位符，值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 *expression* 中使用的表达式属性名称占位符的替换内容。

** `expressionValues` **  
以键值对形式替换表达式属性值占位符。键对应于 expression 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。必须指定此值。该字段是可选的，只应填充 expression 中使用的表达式属性值占位符的替换内容。

** `returnValuesOnConditionCheckFailure` **  
指定在条件检查失败时是否重新检索 DynamoDB 中的项目。检索到的项目将位于 `ctx.result.cancellationReasons[<index>].item` 中，其中 `<index>` 是未通过条件检查的请求项目的索引。该值默认为 true。

# 投影
<a name="js-aws-appsync-resolver-reference-dynamodb-projections"></a>

在使用 `GetItem`、`Scan`、`Query`、`BatchGetItem` 和 `TransactGetItems` 操作读取 DynamoDB 中的对象时，您可以选择指定一个投影以指定所需的属性。投影属性具有以下结构，与筛选条件类似：

```
type DynamoDBExpression = {
  expression: string;
  expressionNames?: { [key: string]: string}
};
```

字段定义如下：

** `expression` **  
投影表达式，它是一个字符串。要检索单个属性，请指定其名称。对于多个属性，名称必须是逗号分隔值。有关编写投影表达式的更多信息，请参阅 [DynamoDB 投影表达式](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html)文档。该字段为必填。

** `expressionNames` **  
以键值对形式替换表达式属性*名称*占位符。键对应于 `expression` 中使用的名称占位符。该值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 `expression` 中使用的表达式属性名称占位符的替换内容。有关 `expressionNames` 的更多信息，请参阅 [DynamoDB 文档](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html)。

## 示例 1
<a name="js-id22"></a>

以下示例是一个函数的投影部分，在该 JavaScript 函数中，DynamoDB `id` 仅返回属`author`性和和：

```
projection : {
    expression : "#author, id",
    expressionNames : {
        "#author" : "author"
    }
}
```

**提示**  
您可以使用访问您的 GraphQL 请求选择集。[selectionSetList](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html#aws-appsync-resolver-context-reference-info-js)可以通过该字段根据您的要求动态构建投影表达式。

**注意**  
在将投影表达式与 `Query` 和 `Scan` 运算一起使用时，`select` 的值必须为 `SPECIFIC_ATTRIBUTES`。有关更多信息，请参阅 [DynamoDB 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-Select)。

# AWS AppSync JavaScript 的解析器函数参考 OpenSearch
<a name="resolver-reference-elasticsearch-js"></a>

亚马逊 OpenSearch 服务的 AWS AppSync 解析器允许您使用 GraphQL 存储和检索账户中 OpenSearch 现有服务域中的数据。此解析器的工作原理是允许您将传入的 GraphQL 请求映射到服务请求，然后将 OpenSearch 服务响应映射 OpenSearch 回 GraphQL。本节介绍支持的 OpenSearch 服务操作的函数请求和响应处理程序。

## 请求
<a name="request-js"></a>

大多数 OpenSearch 服务请求对象都有一个共同的结构，其中只有几个部分会发生变化。以下示例针对 OpenSearch 服务域运行搜索，其中文档的类型`post`和索引位于服务域下`id`。搜索参数在 `body` 部分定义，而许多常用查询子句在 `query` 字段中定义。此示例将搜索在文档的 `"Nadia"` 字段中包含 `"Bailey"` 和/或 `author` 的文档。

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          bool: {
            should: [
              { match: { author: 'Nadia' } },
              { match: { author: 'Bailey' } },
            ],
          },
        },
      },
    },
  };
}
```

## 响应
<a name="response-mapping-template"></a>

与其他数据源一样， OpenSearch 服务会向发送需要转换为 GraphQL 的响应。 AWS AppSync 

大多数 GraphQL 查询都是从 OpenSearch 服务响应中查找该`_source`字段。由于您可以通过搜索返回单个文档或文档列表，因此 S OpenSearch ervice 中使用了两种常见的响应模式：

 **结果列表** 

```
export function response(ctx) {
  const entries = [];
  for (const entry of ctx.result.hits.hits) {
    entries.push(entry['_source']);
  }
  return entries;
}
```

 **单个项目** 

```
export function response(ctx) {
  return ctx.result['_source']
}
```

## `operation` 字段
<a name="operation-field"></a>

**注意**  
这仅适用于请求处理程序。

 AWS AppSync 发送到 OpenSearch 服务域的 HTTP 方法或动词（GET、POST、PUT、HEAD 或 DELETE）。键和值都必须是字符串。

```
"operation" : "PUT"
```

## `path` 字段
<a name="path-field"></a>

**注意**  
这仅适用于请求处理程序。

来自的 OpenSearch 服务请求的搜索路径 AWS AppSync。这构成了操作的 HTTP 谓词的 URL。键和值都必须是字符串。

```
"path" : "/indexname/type"

"path" : "/indexname/type/_search"
```

评估请求处理程序时，此路径将作为 HTTP 请求的一部分发送，包括 OpenSearch 服务域。例如，上一个示例可能会转换为：

```
GET https://opensearch-domain-name.REGION.es.amazonaws.com/indexname/type/_search
```

## `params` 字段
<a name="params-field"></a>

**注意**  
这仅适用于请求处理程序。

用于指定搜索执行的操作，最常见的是在**正文**中设置**查询**值。但是，可以配置若干其他功能，如响应的格式设置。
+  **headers** 

  标头信息（为键值对）。键和值都必须是字符串。例如：

  ```
  "headers" : {
      "Content-Type" : "application/json"
  }
  ```

   
**注意**  
AWS AppSync 目前仅支持 JSON 作为`Content-Type`。
+  **queryString** 

  指定常用选项的键值对，如 JSON 响应的代码格式设置。键和值都必须是字符串。例如，如果您要获得格式正确的 JSON，应使用：

  ```
  "queryString" : {
      "pretty" : "true"
  }
  ```
+  **body** 

  这是您请求的主要部分， AWS AppSync 允许您针对您的 OpenSearch 服务域名起草格式良好的搜索请求。键必须是组成对象的一个字符串。下面介绍了几个演示。

 **示例 1** 

返回城市与“seattle”匹配的所有文档：

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: { from: 0, size: 50, query: { match: { city: 'seattle' } } },
    },
  };
}
```

 **示例 2** 

返回将“washington”作为城市或州匹配的所有文档。

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          multi_match: { query: 'washington', fields: ['city', 'state'] },
        },
      },
    },
  };
}
```

## 传递变量
<a name="passing-variables"></a>

**注意**  
这仅适用于请求处理程序。

您也可以在评估请求处理程序期间传递变量。例如，假设您具有以下 GraphQL 查询，如下所示：

```
query {
    searchForState(state: "washington"){
        ...
    }
}
```

函数请求处理程序可能如下所示：

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          multi_match: { query: ctx.args.state, fields: ['city', 'state'] },
        },
      },
    },
  };
}
```

# AWS AppSync JavaScript Lambda 的解析器函数参考
<a name="resolver-reference-lambda-js"></a>

您可以使用 AWS AppSync 函数和解析器来调用位于您账户中的 Lambda 函数。您可以在将请求有效载荷和 Lambda 函数响应返回给客户端之前对其进行调整。您还可以指定在请求对象中执行的操作类型。本节介绍了支持的 Lambda 操作的请求。

## 请求对象
<a name="request-object-js"></a>

Lambda 请求对象可以处理与您的 Lambda 函数相关的字段：

```
export type LambdaRequest = {
  operation: 'Invoke' | 'BatchInvoke';
  invocationType?: 'RequestResponse' | 'Event';
  payload: unknown;
};
```

以下示例使用了一个 `invoke` 操作，其有效载荷数据是 GraphQL 架构中的 `getPost` 字段以及来自上下文的参数：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

整个映射文档作为输入传递给您的 Lambda 函数，因此，上一示例现在如下所示：

```
{
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": {
      "input": {
        "id": "postId1",
      }
    }
  }
}
```

### 操作
<a name="operation-js"></a>

Lambda 数据来源允许您在 `operation` 字段中定义两个操作：`Invoke` 和 `BatchInvoke`。该`Invoke`操作允许 AWS AppSync 你为每个 GraphQL 字段解析器调用你的 Lambda 函数。 `BatchInvoke`指示 AWS AppSync 对当前 GraphQL 字段进行批量请求。`operation` 字段为必填项。

对于 `Invoke`，解析的请求与 Lambda 函数的输入有效载荷匹配。我们来修改上面的示例：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

这已解析并传递给 Lambda 函数，可能如下所示：

```
{
  "operation": "Invoke",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

对于 `BatchInvoke`，请求应用于批次中的每个字段解析器。为简洁起见，将所有请求`payload`值 AWS AppSync 合并到与请求对象匹配的单个对象下的列表中。以下示例请求处理程序显示了合并：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: ctx,
  };
}
```

将评估该请求并解析为以下映射文档：

```
{
  "operation": "BatchInvoke",
  "payload": [
    {...}, // context for batch item 1
    {...}, // context for batch item 2
    {...}  // context for batch item 3
  ]
}
```

`payload` 列表的每个元素对应于一个批处理项目。Lambda 函数也预期返回列表形状的响应，并与请求中发送的项目顺序匹配：

```
[
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 1
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 2
  { "data": {...}, "errorMessage": null, "errorType": null }  // result for batch item 3
]
```

### 有效载荷
<a name="payload-js"></a>

`payload` 字段是一个容器，用于将任何数据传递给 Lambda 函数。如果该`operation`字段设置为`BatchInvoke`，则 AWS AppSync 将现有`payload`值换成一个列表。`payload` 字段为可选项。

### 调用类型
<a name="async-invocation-type-js"></a>

Lambda 数据来源让您可以定义两个调用类型：`RequestResponse` 和 `Event`。这些调用类型等同于 [Lambda API](https://docs.aws.amazon.com//lambda/latest/api/API_Invoke.html) 中定义的调用类型。`RequestResponse`调用类型允许 AWS AppSync 同步调用您的 Lambda 函数以等待响应。`Event` 调用让您可以异步调用 Lambda 函数。有关 Lambda 如何处理 `Event` 调用类型请求的更多信息，请参阅[异步调用](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html)。`invocationType` 字段为可选项。如果请求中未包含此字段， AWS AppSync 则默认为`RequestResponse`调用类型。

对于任何 `invocationType` 字段，解析的请求与 Lambda 函数的输入有效载荷匹配。我们来修改上面的示例：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    invocationType: 'Event',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

这已解析并传递给 Lambda 函数，可能如下所示：

```
{
  "operation": "Invoke",
  "invocationType": "Event",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

当该`BatchInvoke`操作与`Event`调用类型字段结合使用时，将以与上述相同的方式 AWS AppSync 合并字段解析器，然后将请求作为异步事件传递给您的 Lambda 函数，并以值列表的形式传送给您的 Lambda 函数。`payload`来自 `Event` 调用类型请求的响应会生成一个没有响应处理程序的 `null` 值：

```
{
  "data": {
    "field": null
  }
}
```

建议您对 `Event` 调用类型解析器禁用解析器缓存，因为如果出现缓存命中，这些解析器不会发送到 Lambda。

## 响应对象
<a name="response-object-js"></a>

与其他数据源一样，您的 Lambda 函数会向其发送一个必须转换为 GraphQL 类型的响应。 AWS AppSync Lambda 函数的结果包含在 `context` 结果属性（`context.result`）中。

如果 Lambda 函数响应形状与 GraphQL 类型形状匹配，您可以使用以下函数响应处理程序转发响应：

```
export function response(ctx) {
  return ctx.result
}
```

没有适用于响应对象的必填字段或形状限制。不过，由于 GraphQL 是强类型的，因此，解析的响应必须与预期的 GraphQL 类型匹配。

## Lambda 函数批处理的响应
<a name="aws-appsync-resolver-reference-lambda-batched-response-js"></a>

如果 `operation` 字段设置为 `BatchInvoke`， AWS AppSync 预计从 Lambda 函数返回项目列表。 AWS AppSync 为了将每个结果映射回原始请求项，响应列表的大小和顺序必须匹配。可以在响应列表中包含 `null` 项目；`ctx.result` 相应地设置为 *null*。

# AWS AppSync JavaScript EventBridge 数据源的解析器函数参考
<a name="resolver-reference-eventbridge-js"></a>

与 EventBridge 数据源一起使用的 AWS AppSync 解析器函数请求和响应允许您向 Amazon EventBridge 总线发送自定义事件。

## 请求
<a name="request-js"></a>

请求处理程序允许您将多个自定义事件发送到 EventBridge 事件总线：

```
export function request(ctx) {
  return {
    "operation" : "PutEvents",
    "events" : [{}]
  }
}
```

 EventBridge `PutEvents`请求的类型定义如下：

```
type PutEventsRequest = {
  operation: 'PutEvents'
  events: {
    source: string
    detail: { [key: string]: any }
    detailType: string
    resources?: string[]
    time?: string // RFC3339 Timestamp format
  }[]
}
```

## 响应
<a name="response-js"></a>

如果`PutEvents`操作成功， EventBridge 则来自的响应将包含在`ctx.result`：

```
export function response(ctx) {
  if(ctx.error)
    util.error(ctx.error.message, ctx.error.type, ctx.result)
  else
    return ctx.result
}
```

执行 `PutEvents` 操作时发生的错误（例如 `InternalExceptions` 或 `Timeouts`）将出现在 `ctx.error` 中。有关常见错误 EventBridge的列表，请参阅[EventBridge 常见错误参考](https://docs.aws.amazon.com/eventbridge/latest/APIReference/CommonErrors.html)。

`result` 将具有以下类型定义：

```
type PutEventsResult = {
  Entries: {
    ErrorCode: string
    ErrorMessage: string
    EventId: string
  }[]
  FailedEntryCount: number
}
```
+ **Entries**

  摄取的事件结果（成功和失败）。如果摄取成功，则在该条目中包含 `EventID`。否则，您可以使用 `ErrorCode` 和 `ErrorMessage` 找出条目的问题。

  对于每条记录，响应元素的索引与请求数组中的索引相同。
+ **FailedEntryCount**

  失败条目数。该值表示为一个整数。

有关响应的更多信息`PutEvents`，请参阅[PutEvents](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEvents.html#API_PutEvents_ResponseElements)。

**示例响应 1**

以下示例是具有两个成功事件的 `PutEvents` 操作：

```
{
    "Entries" : [ 
        {
            "EventId": "11710aed-b79e-4468-a20b-bb3c0c3b4860"
        }, 
        {
            "EventId": "d804d26a-88db-4b66-9eaf-9a11c708ae82"
        }
    ],
    "FailedEntryCount" : 0
}
```

**示例响应 2**

以下示例是具有三个事件的 `PutEvents` 操作，其中的两个事件是成功事件，一个是失败事件：

```
{
    "Entries" : [ 
        {
            "EventId": "11710aed-b79e-4468-a20b-bb3c0c3b4860"
        }, 
        {
            "EventId": "d804d26a-88db-4b66-9eaf-9a11c708ae82"
        },
        {
            "ErrorCode" : "SampleErrorCode",
            "ErrorMessage" : "Sample Error Message"
        }
    ],
    "FailedEntryCount" : 1
}
```

## `PutEvents` 字段
<a name="putevents-field"></a>

`PutEvents` 包含以下映射模板字段：
+ **版本**

  `version` 字段是所有请求映射模板通用的，用于定义模板使用的版本。该字段为必填。该值`2018-05-29`是 EventBridge 映射模板支持的唯一版本。
+ **操作**

  唯一支持的操作是 `PutEvents`。通过执行该操作，您可以将自定义事件添加到事件总线中。
+ **Events**

  将添加到事件总线的事件数组。应该为该数组分配 1-10 个项目。

  `Event` 对象具有以下字段：
  + `"source"`：定义事件源的字符串。
  + `"detail"`：可用于附加事件相关信息的 JSON 对象。该字段可以是空映射 (`{ }`)。
  + `"detailType`：指定事件类型的字符串。
  + `"resources"`：指定事件中涉及的资源的 JSON 字符串数组。该字段可以是空数组。
  + `"time"`：以字符串形式提供的事件时间戳。这应遵循[RFC3339](https://www.rfc-editor.org/rfc/rfc3339.txt)时间戳格式。

以下片段是一些有效 `Event` 对象示例：

**示例 1**

```
{
    "source" : "source1",
    "detail" : {
        "key1" : [1,2,3,4],
        "key2" : "strval"
    },
    "detailType" : "sampleDetailType",
    "resources" : ["Resouce1", "Resource2"],
    "time" : "2022-01-10T05:00:10Z"
}
```

**示例 2**

```
{
    "source" : "source1",
    "detail" : {},
    "detailType" : "sampleDetailType"
}
```

**示例 3**

```
{
    "source" : "source1",
    "detail" : {
        "key1" : 1200
    },
    "detailType" : "sampleDetailType",
    "resources" : []
}
```

# AWS AppSync JavaScript `None`数据源的解析器函数参考
<a name="resolver-reference-none-js"></a>

使用数据源类型*为 None* 的 AWS AppSync 解析器函数请求和响应，您可以调整对 AWS AppSync 本地操作的请求。

## 请求
<a name="request-js"></a>

请求处理程序可能很简单，并允许您通过 `payload` 字段传递尽可能多的上下文信息。

```
type NONERequest = {
  payload: any;
};
```

以下是一个将字段参数传递给负载的示例：

```
export function request(ctx) {
  return {
    payload: context.args
  };
}
```

`payload` 字段的值将转发到函数响应处理程序，并且可以在 `context.result` 中使用。

## 有效载荷
<a name="payload-js"></a>

`payload` 字段是一个容器，可用于传递任何数据以供函数响应处理程序使用。

 `payload` 字段为可选项。

## 响应
<a name="response-js"></a>

由于没有数据来源，`payload` 字段的值将转发到函数响应处理程序，并在 `context.result` 属性上设置该值。

如果 `payload` 字段值的形状与 GraphQL 类型的形状完全匹配，您可以使用以下响应处理程序转发响应：

```
export function response(ctx) {
  return ctx.result;
}
```

没有适用于返回响应的必填字段或形状限制。不过，由于 GraphQL 是强类型的，因此，解析的响应必须与预期的 GraphQL 类型匹配。

# AWS AppSync JavaScript HTTP 的解析器函数参考
<a name="resolver-reference-http-js"></a>

使用 AWS AppSync HTTP 解析器函数，您可以将来自的请求发送 AWS AppSync 到任何 HTTP 端点，并将来自您的 HTTP 端点的响应发送回到 AWS AppSync。使用您的请求处理程序，您可以提供 AWS AppSync 有关要调用的操作性质的提示。本节介绍了支持的 HTTP 解析器的各种配置。

## 请求
<a name="request-js"></a>

```
type HTTPRequest = {
  method: 'PUT' | 'POST' | 'GET' | 'DELETE' | 'PATCH';
  params?: {
    query?: { [key: string]: any };
    headers?: { [key: string]: string };
    body?: any;
  };
  resourcePath: string;
};
```

以下代码片段是一个 HTTP POST 请求示例，其正文为 `text/plain`：

```
export function request(ctx) {
  return {
    method: 'POST',
    params: {
      headers: { 'Content-Type': 'text/plain' },
      body: 'this is an example of text body',
    },
    resourcePath: '/',
  };
}
```

## 方法
<a name="method-js"></a>

**注意**  
这仅适用于请求处理程序。

 AWS AppSync 发送到 HTTP 端点的 HTTP 方法或动词（GET、POST、PUT、PATCH 或 DELETE）。

```
"method": "PUT"
```

## ResourcePath
<a name="resourcepath-js"></a>

 

**注意**  
这仅适用于请求处理程序。

您要访问的资源路径。资源路径与 HTTP 数据源中的端点一起构成 AWS AppSync 服务向其发出请求的 URL。

```
"resourcePath": "/v1/users"
```

在评估请求时，该路径将作为 HTTP 请求的一部分发送，包括 HTTP 终端节点。例如，上一个示例可能会转换为如下所示：

```
PUT <endpoint>/v1/users
```

## 参数字段
<a name="params-field-js"></a>

**注意**  
这仅适用于请求处理程序。

用于指定搜索执行的操作，最常见的是在**正文**中设置**查询**值。但是，可以配置若干其他功能，如响应的格式设置。

** **headers** **  
标头信息（为键值对）。键和值都必须是字符串。  
例如：  

```
"headers" : {
    "Content-Type" : "application/json"
}
```
目前支持的 `Content-Type` 标头包括：  

```
text/*
application/xml
application/json
application/soap+xml
application/x-amz-json-1.0
application/x-amz-json-1.1
application/vnd.api+json
application/x-ndjson
```
您无法设置以下 HTTP 标头：  

```
HOST
CONNECTION
USER-AGENT
EXPECTATION
TRANSFER_ENCODING
CONTENT_LENGTH
```

** **query** **  
指定常用选项的键值对，如 JSON 响应的代码格式设置。键和值都必须是字符串。以下示例显示如何发送 `?type=json` 格式的请求字符串：  

```
"query" : {
    "type" : "json"
}
```

** **body** **  
正文包含您选择要设置的 HTTP 请求正文。请求正文始终是 UTF-8 编码格式的字符串，除非内容类型指定字符集。  

```
"body":"body string"
```

## 响应
<a name="response-js"></a>

请参见[此处](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-http-resolvers-js.html)的示例。

# AWS AppSync JavaScript Amazon RDS 的解析器函数参考
<a name="resolver-reference-rds-js"></a>

 AWS AppSync RDS 函数和解析器允许开发人员使用 RDS 数据 API 向 Amazon Aurora 集群数据库发送SQL查询，并获取这些查询的结果。您可以使用带有模块`sql`标签的模板或使用`rds`模块 AWS AppSync的`select`、`insert`、和`remove`帮助函数来编写发送到 Data API 的SQL语句。`rds` `update` AWS AppSync 利用 RDS 数据服务的[https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html)操作对数据库运行 SQL 语句。

**主题**
+ [带 SQL 标签的模板](#sql-tagged-templates)
+ [创建语句](#creating-statements)
+ [检索数据](#retrieving-data)
+ [实用程序函数](#utility-functions)
+ [SQL 选择](#utility-functions-select)
+ [SQL 插入](#utility-functions-insert)
+ [SQL 更新](#utility-functions-update)
+ [SQL 删除](#utility-functions-delete)
+ [转换](#casting)

## 带 SQL 标签的模板
<a name="sql-tagged-templates"></a>

AWS AppSync的`sql`标记模板使您能够使用模板表达式创建可在运行时接收动态值的静态语句。 AWS AppSync 根据表达式值构建变量映射以构造发送到 Amazon Aurora 无服务器数据 API 的[https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html)查询。使用此方法，运行时传递的动态值不可能修改原始语句，这可能会导致意外执行。所有动态值都作为参数传递，不能修改原始语句，也不会由数据库执行。这使您的查询不太容易受到 SQL 注入攻击。

**注意**  
在所有情况下，在编写 SQL 语句时，都应遵循安全准则，以正确处理作为输入收到的数据。

**注意**  
带 `sql` 标签的模板仅支持传递变量值。不能使用表达式来动态指定列名称或表名称。但是，您可以使用实用程序函数来构建动态语句。

在以下示例中，我们创建了一个查询，该查询根据运行时在 GraphQL 查询中动态设置的 `col` 参数值进行筛选。只能使用标签表达式将该值添加到语句中：

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
  const query = sql`
SELECT * FROM table 
WHERE column = ${ctx.args.col}`
  ;
  return createMySQLStatement(query);
}
```

借助于通过变量映射传递所有动态值，我们依靠数据库引擎来安全地处理和清理值。

## 创建语句
<a name="creating-statements"></a>

函数和解析器可以与 MySQL 和 PostgreSQL 数据库进行交互。分别使用 `createMySQLStatement` 和 `createPgStatement` 来构建语句。例如，`createMySQLStatement` 可以创建 MySQL 查询。这些函数最多可接受两条语句，在请求应立即检索结果时很有用。使用 MySQL，您可以执行：

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { id, text } = ctx.args;
    const s1 = sql`insert into Post(id, text) values(${id}, ${text})`;
    const s2 = sql`select * from Post where id = ${id}`;
    return createMySQLStatement(s1, s2);
}
```

**注意**  
`createPgStatement` 和 `createMySQLStatement` 不转义或引用使用带 `sql` 标签的模板构建的语句。

## 检索数据
<a name="retrieving-data"></a>

您执行的 SQL 语句的结果可在响应处理程序的 `context.result` 对象中提供。结果是一个 JSON 字符串，其中包含来自 `ExecuteStatement` 操作的[响应元素](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html#API_ExecuteStatement_ResponseElements)。解析后，结果具有以下形状：

```
type SQLStatementResults = {
    sqlStatementResults: {
        records: any[];
        columnMetadata: any[];
        numberOfRecordsUpdated: number;
        generatedFields?: any[]
    }[]
}
```

您可以使用 `toJsonObject` 实用程序将结果转换为表示返回行的 JSON 对象列表。例如：

```
import { toJsonObject } from '@aws-appsync/utils/rds';

export function response(ctx) {
    const { error, result } = ctx;
    if (error) {
        return util.appendError(
            error.message,
            error.type,
            result
        )
    }
    return toJsonObject(result)[1][0]
}
```

请注意，`toJsonObject` 返回语句结果数组。如果您提供了一条语句，则数组长度为 `1`。如果您提供了两条语句，则数组长度为 `2`。数组中的每个结果都包含 `0` 行或多行。如果结果值无效或不符合预期，则 `toJsonObject` 返回 `null`。

## 实用程序函数
<a name="utility-functions"></a>

您可以使用 AWS AppSync RDS 模块的实用工具帮助程序与您的数据库进行交互。

### SQL 选择
<a name="utility-functions-select"></a>

`select` 实用程序会创建一条 `SELECT` 语句来查询您的关系数据库。

**基本用法**

在其基本形式中，您可以指定要查询的表：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

请注意，您也可以在表标识符中指定架构：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**指定列**

您可以使用 `columns` 属性指定列。如果未将其设置为某个值，则它默认为 `*`：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

您也可以指定列的表：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**限制和偏移**

您可以将 `limit` 和 `offset` 应用于查询：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**排序依据**

您可以使用 `orderBy` 属性对结果进行排序。提供指定列和可选 `dir` 属性的对象数组：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**筛选条件**

您可以使用特殊条件对象来构建筛选条件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

您也可以组合筛选条件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

您也可以创建 `OR` 语句：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用 `not` 来否定条件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用以下运算符来比较值：


| 
| 
| 运算符 | 说明 | 可能的值类型 | 
| --- |--- |--- |
| eq | Equal | 数字、字符串、布尔值 | 
| ne | Not equal | 数字、字符串、布尔值 | 
| le | Less than or equal | 数字，字符串 | 
| lt | Less than | 数字，字符串 | 
| ge | Greater than or equal | 数字，字符串 | 
| gt | Greater than | 数字，字符串 | 
| contains | like | 字符串 | 
| 不包含 | 不像 | 字符串 | 
| 开始于 | 以前缀开头 | 字符串 | 
| 介于 | 在两个值之间 | 数字，字符串 | 
| 属性存在 | 该属性不为空 | 数字、字符串、布尔值 | 
| size | 检查元素的长度 | 字符串 | 

### SQL 插入
<a name="utility-functions-insert"></a>

`insert` 实用程序提供了一种通过 `INSERT` 操作在数据库中插入单行项目的简单方法。

**单个项目插入**

要插入项目，请指定表，然后传入您的值对象。对象键映射到您的表列。列名称会自动转义，并使用变量映射将值发送到数据库：

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**MySQL 用例**

您可以组合 `insert` 后跟 `select` 来检索您插入的行：

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Postgres 用例**

借助 Postgres，您可以使用 [https://www.postgresql.org/docs/current/dml-returning.html](https://www.postgresql.org/docs/current/dml-returning.html) 从插入的行中获取数据。它接受 `*` 或列名称数组：

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

### SQL 更新
<a name="utility-functions-update"></a>

`update` 实用程序允许您更新现有行。您可以使用条件对象将更改应用于满足条件的所有行中的指定列。例如，假设我们有一个允许我们进行这种突变的架构。我们要将 `Person` 的 `name` 更新为 `id` 值 `3`，但仅限我们自 `2000` 年开始就已知道它们 (`known_since`)：

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

更新解析器如下所示：

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

我们可以在条件中添加一项检查，以确保只更新主键 `id` 等于 `3` 的行。同样，对于 Postgres `inserts`，您可以使用 `returning` 返回修改后的数据。

### SQL 删除
<a name="utility-functions-delete"></a>

`remove` 实用程序允许您删除现有行。您可以在满足条件的所有行上使用条件对象。请注意，`delete`这是中的保留关键字 JavaScript。 `remove`应该改用：

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

## 转换
<a name="casting"></a>

在某些情况下，您可能希望在语句中使用更具体的正确对象类型。您可以使用提供的类型提示来指定参数的类型。 AWS AppSync 支持与数据 API [相同的类型提示](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint)。您可以使用 AWS AppSync `rds`模块中的`typeHint`函数来转换参数。

以下示例允许您将数组作为强制转换为 JSON 对象的值发送。我们使用 `->` 运算符来检索 JSON 数组中 `index` 为 `2` 的元素：

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

在处理和比较 `DATE`、`TIME` 和 `TIMESTAMP` 时，强制转换也很有用：

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

下面是另一个示例，显示如何发送当前日期和时间：

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**可用的类型提示**
+ `typeHint.DATE` – 相应的参数作为 `DATE` 类型的对象发送到数据库。接受的格式为 `YYYY-MM-DD`。
+ `typeHint.DECIMAL` – 相应的参数作为 `DECIMAL` 类型的对象发送到数据库。
+ `typeHint.JSON` – 相应的参数作为 `JSON` 类型的对象发送到数据库。
+ `typeHint.TIME` – 相应的字符串参数值作为 `TIME` 类型的对象发送到数据库。接受的格式为 `HH:MM:SS[.FFF]`。
+ `typeHint.TIMESTAMP` – 相应的字符串参数值作为 `TIMESTAMP` 类型的对象发送到数据库。接受的格式为 `YYYY-MM-DD HH:MM:SS[.FFF]`。
+ `typeHint.UUID` – 相应的字符串参数值作为 `UUID` 类型的对象发送到数据库。

# AWS AppSync JavaScript 亚马逊 Bedrock 运行时的解析器和函数参考
<a name="resolver-reference-bedrock-js"></a>

您可以使用 AWS AppSync 函数和解析器在您的 Amazon Bedrock 上调用模型。 AWS 账户您可以在将请求有效载荷和模型调用函数响应返回给客户端之前对其进行调整。您可以使用 Amazon Bedrock 运行时的 `InvokeModel` API 或 `Converse` API。本节介绍了支持的 Amazon Bedrock 操作对应的请求。

**注意**  
AWS AppSync 仅支持在 10 秒内完成的同步调用。不可能拨打 Amazon Bedrock 的直播 APIs。 AWS AppSync 仅支持在与 API 相同的区域调用基础模型和[推理配置文件](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html)。 AWS AppSync 

## 请求对象
<a name="request_object"></a>

`InvokeModel` 请求对象允许您与 Amazon Bedrock 的 `InvokeModel` API 进行交互。

```
type BedrockInvokeModelRequest = {
  operation: 'InvokeModel';
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
}
```

`Converse` 请求对象允许您与 Amazon Bedrock 的 `Converse` API 进行交互。

```
type BedrockConverseRequest = {
  operation: 'Converse';
  modelId: string;
  messages: BedrockMessage[];
  additionalModelRequestFields?: any;
  additionalModelResponseFieldPaths?: string[];
  guardrailConfig?: BedrockGuardrailConfig;
  inferenceConfig?: BedrockInferenceConfig;
  promptVariables?: { [key: string]: BedrockPromptVariableValues }[];
  system?: BedrockSystemContent[];
  toolConfig?: BedrockToolConfig;
}
```

有关更多详细信息，请参阅本主题后面的 [类型参考](#type-reference-bedrock) 部分。

在你的函数和解析器中，你可以直接构建请求对象，也可以使用 @aws-中的辅助函数appsync/utils/ai来创建请求。在请求中指定模型 ID（modelId）时，您可以使用模型 ID 或模型 ARN。

以下示例使用该`invokeModel`函数使用 Amazon Titan Text G1-Lite（亚马逊）来汇总文本。 titan-text-lite-v1)。配置的护栏用于识别、屏蔽或过滤提示流中不需要的内容。有关 [Amazon Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) 的更多信息，请参阅《Amazon Bedrock 用户指南》**。

**重要**  
您负责确保应用程序开发的安全并防止提示注入等漏洞。要了解更多信息，请参阅《Amazon Bedrock 用户指南》**中的[提示注入安全](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-injection.html)。

```
import { invokeModel } from '@aws-appsync/utils/ai'
export function request(ctx) {
  return invokeModel({
    modelId: 'amazon.titan-text-lite-v1',
    guardrailIdentifier: "zabcd12345678",
    guardrailVersion: "1",
    body: { inputText: `Summarize this text in less than 100 words. : \n<text>${ctx.stash.text ?? ctx.env.DEFAULT_TEXT}</text>` },
  })
}

export function response(ctx) {
  return ctx.result.results[0].outputText
}
```

以下示例使用了 `converse` 函数，并指定了一个跨区域推理配置文件（us.anthropic.claude-3-5-haiku-20241022-v1:0）。有关 Amazon Bedrock 的[推理配置文件先决条件](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-prereq.html)的更多信息，请参阅《Amazon Bedrock 用户指南》**。

**提醒**：您负责确保应用程序开发的安全并防止提示注入等漏洞。

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return converse({
    modelId: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 
${ctx.args.explain ? 'Explain your answer' : 'Do not explain your answer'}.
Assume a database with the following tables and columns exists:

Customers:  
- customer_id (INT, PRIMARY KEY)  
- first_name (VARCHAR)  
- last_name (VARCHAR)  
- email (VARCHAR)  
- phone (VARCHAR)  
- address (VARCHAR)  
- city (VARCHAR)  
- state (VARCHAR)  
- zip_code (VARCHAR)  
  
Products:  
- product_id (INT, PRIMARY KEY)  
- product_name (VARCHAR)  
- description (TEXT)  
- category (VARCHAR)  
- price (DECIMAL)  
- stock_quantity (INT)  

Orders:  
- order_id (INT, PRIMARY KEY)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- order_date (DATE)  
- total_amount (DECIMAL)  
- status (VARCHAR)  

Order_Items:  
- order_item_id (INT, PRIMARY KEY)  
- order_id (INT, FOREIGN KEY REFERENCES Orders)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- quantity (INT)  
- price (DECIMAL)  

Reviews:  
- review_id (INT, PRIMARY KEY)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- rating (INT)  
- comment (TEXT)  
- review_date (DATE)`,
      },
    ],
    messages: [
      {
        role: 'user',
        content: [{ text: `<request>${ctx.args.text}:</request>` }],
      },
    ],
  })
}

export function response(ctx) {
  return ctx.result.output.message.content[0].text
}
```

以下示例使用 `converse` 来创建结构化响应。请注意，我们使用环境变量作为数据库架构引用，并配置了护栏来帮助防止攻击。

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return generateObject({
    modelId: ctx.env.HAIKU3_5, // keep the model in an env variable
    prompt: ctx.args.query,
    shape: objectType(
      {
        sql: stringType('the sql query to execute as a javascript template string.'),
        parameters: objectType({}, 'the placeholder parameters for the query, if any.'),
      },
      'the sql query to execute along with the place holder parameters',
    ),
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 

Assume a database with the following tables and columns exists:

${ctx.env.DB_SCHEMA_CUSTOMERS}
${ctx.env.DB_SCHEMA_ORDERS}
${ctx.env.DB_SCHEMA_ORDER_ITEMS}
${ctx.env.DB_SCHEMA_PRODUCTS}
${ctx.env.DB_SCHEMA_REVIEWS}`,
      },
    ],
    guardrailConfig: { guardrailIdentifier: 'iabc12345678', guardrailVersion: 'DRAFT' },
  })
}

export function response(ctx) {
  return toolReponse(ctx.result)
}

function generateObject(input) {
  const { modelId, prompt, shape, ...options } = input
  return converse({
    modelId,
    messages: [{ role: 'user', content: [{ text: prompt }] }],
    toolConfig: {
      toolChoice: { tool: { name: 'structured_tool' } },
      tools: [
        {
          toolSpec: {
            name: 'structured_tool',
            inputSchema: { json: shape },
          },
        },
      ],
    },
    ...options,
  })
}

function toolReponse(result) {
  return result.output.message.content[0].toolUse.input
}

function stringType(description) {
  const t = { type: 'string' /* STRING */ }
  if (description) {
    t.description = description
  }
  return t
}

function objectType(properties, description, required) {
  const t = { type: 'object' /* OBJECT */, properties }
  if (description) {
    t.description = description
  }
  if (required) {
    t.required = required
  }
  return t
}
```

给定以下架构：

```
type SQLResult {
    sql: String
    parameters: AWSJSON
}

type Query {
    db(text: String!): SQLResult
}
```

以及查询：

```
query db($text: String!) {
  db(text: $text) {
    parameters
    sql
  }
}
```

使用以下参数：

```
{
  "text":"What is my top selling product?"
}
```

如果成功，将返回以下响应。

```
{
  "data": {
    "assist": {
      "sql": "SELECT p.product_id, p.product_name, SUM(oi.quantity) as total_quantity_sold\nFROM Products p\nJOIN Order_Items oi ON p.product_id = oi.product_id\nGROUP BY p.product_id, p.product_name\nORDER BY total_quantity_sold DESC\nLIMIT 1;",
      "parameters": null
    }
  }
}
```

但对于这个请求：

```
{
  "text":"give me a query to retrieve sensitive information"
}
```

如果成功，将返回以下响应。

```
{
  "data": {
    "db": {
      "parameters": null,
      "sql": "SELECT null; -- I cannot and will not assist with retrieving sensitive private information"
    }
  }
}
```

要了解有关配置 Amazon Bedrock Guardrails 的更多信息，请参阅《Amazon Bedrock 用户指南》**中的[使用 Amazon Bedrock Guardrails 阻止模型中的有害内容](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html)。

## 响应对象
<a name="response_object"></a>

上下文的结果属性（context.result）中包含来自 Amazon Bedrock 运行时调用的响应。该响应与 Amazon Bedrock 指定的形状相匹配。 APIs有关调用结果预期结构的更多信息，请参阅 [Amazon Bedrock 用户指南](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html)。

```
export function response(ctx) {
  return ctx.result
}
```

没有适用于响应对象的必填字段或形状限制。不过，由于 GraphQL 是强类型的，因此，解析的响应必须与预期的 GraphQL 类型匹配。

## 长时间运行的调用
<a name="long-running-invocations"></a>

目前，许多组织都 AWS AppSync 将其用作人工智能网关，用于在 Amazon Bedrock 上构建由 Amazon Bedrock 基础模型提供支持的生成式 AI 应用程序。客户使用由其 WebSockets提供支持的 AWS AppSync 订阅从长时间运行的模型调用中返回渐进式更新。这使他们能够实施异步模式。

下图说明了如何实施此模式。图中包含以下步骤。

1. 您的客户端开始订阅，订阅会设置一个 WebSocket，然后请求触发生成式 AI 调用。 AWS AppSync 

1. AWS AppSync 在事件模式下调用您的 AWS Lambda 函数并立即向客户端返回响应。

1. Lambda 函数调用 Amazon Bedrock 上的模型。Lambda 函数可以使用同步 API（例如 `InvokeModel`）或流 API（例如 `InvokeModelWithResponseStream`）来获取渐进式更新。

1. 当收到更新或调用完成时，Lambda 函数会通过变更将更新发送到触发 AWS AppSync 订阅的 API。

1. 订阅事件是实时发送的，并由您的客户通过以下方式接收 WebSocket。

![\[该图表演示了使用 AWS AppSync 订阅从 Amazon Bedrock 模型返回更新的工作流程。\]](http://docs.aws.amazon.com/zh_cn/appsync/latest/devguide/images/bedrock-workflow.png)


## 类型参考
<a name="type-reference-bedrock"></a>

```
export type BedrockMessage = {
  role: 'user' | 'assistant' | string;
  content: BedrockMessageContent[];
};

export type BedrockMessageContent =
  | { text: string }
  | { guardContent: BedrockGuardContent }
  | { toolResult: BedrockToolResult }
  | { toolUse: BedrockToolUse };

export type BedrockGuardContent = {
  text: BedrockGuardContentText;
};

export type BedrockGuardContentText = {
  text: string;
  qualifiers?: ('grounding_source' | 'query' | 'guard_content' | string)[];
};

export type BedrockToolResult = {
  content: BedrockToolResultContent[];
  toolUseId: string;
  status?: string;
};

export type BedrockToolResultContent = { json: any } | { text: string };

export type BedrockToolUse = {
  input: any;
  name: string;
  toolUseId: string;
};

export type ConversePayload = {
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
};

export type BedrockGuardrailConfig = {
  guardrailIdentifier: string;
  guardrailVersion: string;
  trace: string;
};

export type BedrockInferenceConfig = {
  maxTokens?: number;
  temperature?: number;
  stopSequences?: string[];
  topP?: number;
};

export type BedrockPromptVariableValues = {
  text: string;
};

export type BedrockToolConfig = {
  tools: BedrockTool[];
  toolChoice?: BedrockToolChoice;
};

export type BedrockTool = {
  toolSpec: BedrockToolSpec;
};

export type BedrockToolSpec = {
  name: string;
  description?: string;
  inputSchema: BedrockInputSchema;
};

export type BedrockInputSchema = {
  json: any;
};

export type BedrockToolChoice =
  | { tool: BedrockSpecificToolChoice }
  | { auto: any }
  | { any: any };

export type BedrockSpecificToolChoice = {
  name: string;
};

export type BedrockSystemContent =
  | { guardContent: BedrockGuardContent }
  | { text: string };

export type BedrockConverseOutput = {
  message?: BedrockMessage;
};

export type BedrockConverseMetrics = {
  latencyMs: number;
};

export type BedrockTokenUsage = {
  inputTokens: number;
  outputTokens: number;
  totalTokens: number;
};

export type BedrockConverseTrace = {
  guardrail?: BedrockGuardrailTraceAsssessment;
};

export type BedrockGuardrailTraceAsssessment = {
  inputAssessment?: { [key: string]: BedrockGuardrailAssessment };
  modelOutput?: string[];
  outputAssessments?: { [key: string]: BedrockGuardrailAssessment };
};

export type BedrockGuardrailAssessment = {
  contentPolicy?: BedrockGuardrailContentPolicyAssessment;
  contextualGroundingPolicy?: BedrockGuardrailContextualGroundingPolicyAssessment;
  invocationMetrics?: BedrockGuardrailInvocationMetrics;
  sensitiveInformationPolicy?: BedrockGuardrailSensitiveInformationPolicyAssessment;
  topicPolicy?: BedrockGuardrailTopicPolicyAssessment;
  wordPolicy?: BedrockGuardrailWordPolicyAssessment;
};

export type BedrockGuardrailContentPolicyAssessment = {
  filters: BedrockGuardrailContentFilter[];
};

export type BedrockGuardrailContentFilter = {
  action: 'BLOCKED' | string;
  confidence: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
  type:
    | 'INSULTS'
    | 'HATE'
    | 'SEXUAL'
    | 'VIOLENCE'
    | 'MISCONDUCT'
    | 'PROMPT_ATTACK'
    | string;
  filterStrength: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
};

export type BedrockGuardrailContextualGroundingPolicyAssessment = {
  filters: BedrockGuardrailContextualGroundingFilter;
};

export type BedrockGuardrailContextualGroundingFilter = {
  action: 'BLOCKED' | 'NONE' | string;
  score: number;
  threshold: number;
  type: 'GROUNDING' | 'RELEVANCE' | string;
};

export type BedrockGuardrailInvocationMetrics = {
  guardrailCoverage?: BedrockGuardrailCoverage;
  guardrailProcessingLatency?: number;
  usage?: BedrockGuardrailUsage;
};

export type BedrockGuardrailCoverage = {
  textCharacters?: BedrockGuardrailTextCharactersCoverage;
};

export type BedrockGuardrailTextCharactersCoverage = {
  guarded?: number;
  total?: number;
};

export type BedrockGuardrailUsage = {
  contentPolicyUnits: number;
  contextualGroundingPolicyUnits: number;
  sensitiveInformationPolicyFreeUnits: number;
  sensitiveInformationPolicyUnits: number;
  topicPolicyUnits: number;
  wordPolicyUnits: number;
};

export type BedrockGuardrailSensitiveInformationPolicyAssessment = {
  piiEntities: BedrockGuardrailPiiEntityFilter[];
  regexes: BedrockGuardrailRegexFilter[];
};

export type BedrockGuardrailPiiEntityFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match: string;
  type:
    | 'ADDRESS'
    | 'AGE'
    | 'AWS_ACCESS_KEY'
    | 'AWS_SECRET_KEY'
    | 'CA_HEALTH_NUMBER'
    | 'CA_SOCIAL_INSURANCE_NUMBER'
    | 'CREDIT_DEBIT_CARD_CVV'
    | 'CREDIT_DEBIT_CARD_EXPIRY'
    | 'CREDIT_DEBIT_CARD_NUMBER'
    | 'DRIVER_ID'
    | 'EMAIL'
    | 'INTERNATIONAL_BANK_ACCOUNT_NUMBER'
    | 'IP_ADDRESS'
    | 'LICENSE_PLATE'
    | 'MAC_ADDRESS'
    | 'NAME'
    | 'PASSWORD'
    | 'PHONE'
    | 'PIN'
    | 'SWIFT_CODE'
    | 'UK_NATIONAL_HEALTH_SERVICE_NUMBER'
    | 'UK_NATIONAL_INSURANCE_NUMBER'
    | 'UK_UNIQUE_TAXPAYER_REFERENCE_NUMBER'
    | 'URL'
    | 'USERNAME'
    | 'US_BANK_ACCOUNT_NUMBER'
    | 'US_BANK_ROUTING_NUMBER'
    | 'US_INDIVIDUAL_TAX_IDENTIFICATION_NUMBER'
    | 'US_PASSPORT_NUMBER'
    | 'US_SOCIAL_SECURITY_NUMBER'
    | 'VEHICLE_IDENTIFICATION_NUMBER'
    | string;
};

export type BedrockGuardrailRegexFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match?: string;
  name?: string;
  regex?: string;
};

export type BedrockGuardrailTopicPolicyAssessment = {
  topics: BedrockGuardrailTopic[];
};

export type BedrockGuardrailTopic = {
  action: 'BLOCKED' | string;
  name: string;
  type: 'DENY' | string;
};

export type BedrockGuardrailWordPolicyAssessment = {
  customWords: BedrockGuardrailCustomWord[];
  managedWordLists: BedrockGuardrailManagedWord[];
};

export type BedrockGuardrailCustomWord = {
  action: 'BLOCKED' | string;
  match: string;
};

export type BedrockGuardrailManagedWord = {
  action: 'BLOCKED' | string;
  match: string;
  type: 'PROFANITY' | string;
};
```