

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

# 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 进行字符串编码。