

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

# AWS AppSync 解析器映射模板参考 (VTL)
<a name="resolver-mapping-template-reference"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

以下几节介绍了如何在映射模板中使用实用程序操作：
+  [解析器映射模板概述](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-overview.html)：详细了解 AWS AppSync中的解析器工作原理。
+  [解析器映射模板编程指南](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html)：详细了解基本 VTL 数据结构和逻辑处理。
+  [解析器映射模板上下文参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html)：详细了解上下文映射及其在解析器中的使用方式。
+  [解析器映射模板实用程序参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html)：详细了解如何使用实用程序来简化代码。
+  [DynamoDB 的解析器映射模板参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html)：详细了解解析器与 DynamoDB 的交互方式。
+  [RDS 的解析器映射模板参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-rds.html)：详细了解解析器结构以及与 RDS 的交互。
+  [解析器映射模板参考 OpenSearch ——详细](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-elasticsearch.html)了解解析器请求和响应结构以及与 Service 的 OpenSearch 交互。
+  [Lambda 的解析器映射模板参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-lambda.html)：详细了解解析器请求和响应结构以及与 Lambda 的交互。
+  的@@ [解析器映射模板参考 EventBridge ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-eventbridge.html) ——详细了解解析器请求和响应结构以及与之交互。 EventBridge
+  [None 数据来源的解析器映射模板参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-none.html)：详细了解解析器请求和响应结构以及与 NONE 数据来源的交互。
+  [HTTP 的解析器映射模板参考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-http.html)：详细了解解析器请求和响应结构以及与 HTTP 端点的交互。

# AWS AppSync 解析器映射模板概述
<a name="resolver-mapping-template-reference-overview"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

AWS AppSync 允许您通过对资源执行操作来响应 GraphQL 请求。对于您希望运行查询或变更的每个 GraphQL 字段，必须附加解析器才能与数据来源通信。通常，通信是通过数据来源特有的参数或操作完成的。

解析器是 GraphQL 和数据来源之间的连接器。它们讲述 AWS AppSync 如何将传入的 GraphQL 请求转换为后端数据源的指令，以及如何将来自该数据源的响应转换回 GraphQL 响应。它们是使用 [Apache Velocity 模板语言 (VTL)](https://velocity.apache.org/engine/1.7/user-guide.html) 编写的，该语言将您的请求作为输入，并输出包含解析器指令的 JSON 文档。您可以使用映射模板执行简单的指令（例如，从 GraphQL 字段中传入参数），也可以执行更复杂的指令（例如，循环访问各个参数以构建项目，然后将该项目插入到 DynamoDB 中）。

有两种类型的解析器利用映射模板的方式略有不同： AWS AppSync 
+ 单位解析器
+ 管道解析器

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

单位解析器是独立的实体，仅包含请求和响应模板。将它们用于简单、单一的操作（例如，列出来自单个数据来源的项目）。
+ 请求模板：在解析 GraphQL 操作后获取传入请求，并将其转换为选定数据来源操作的请求配置。
+ 响应模板：解释来自数据来源的响应，并将其映射到 GraphQL 字段输出类型的形状。

## 管道解析器
<a name="pipeline-resolvers"></a>

管道解析器包含一个或多个按顺序执行的*函数*。每个函数包含一个请求模板和一个响应模板。管道解析器还具有一个*之前* 模板和一个*之后* 模板，它们位于模板包含的一系列函数两侧。*之后* 模板映射到 GraphQL 字段输出类型。管道解析器与单位解析器的不同之处在于响应模板映射输出的方式。管道解析器可以映射到所需的任何输出，包括另一个函数的输入或管道解析器的*之后* 模板。

 管道解析器*函数* 允许您编写可在架构中的多个解析器之间重复使用的通用逻辑。函数直接附加到数据来源，并且像单位解析器一样，包含相同的请求和响应映射模板格式。

下图说明了左侧单位解析器和右侧管道解析器的流程。

![\[与单个数据来源通信的单位解析器的图表以及与多个数据来源通信的管道解析器的图表。\]](http://docs.aws.amazon.com/zh_cn/appsync/latest/devguide/images/unit-pipeline-resolver.png)


管道解析器包含单位解析器支持的功能的超集以及更多功能，但代价是稍微复杂一些。

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

管道解析器由**之前**映射模板、**之后**映射模板和一组函数组成。每个函数具有对数据来源执行的**请求**映射模板和**响应**映射模板。由于管道解析器将执行委托给函数列表，因此它不会链接到任何数据来源。单位解析器和函数是对数据来源执行操作的基元。有关更多信息，请参阅[解析器映射模板概述](#aws-appsync-resolver-mapping-template-reference-overview)。

#### 之前映射模板
<a name="before-mapping-template"></a>

管道解析器的请求映射模板或**预备**步骤允许您在执行定义的函数之前执行一些准备逻辑。

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

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

#### 之后映射模板
<a name="after-mapping-template"></a>

管道解析器的响应映射模板或**后续**步骤允许您执行从最后一个函数的输出到预期 GraphQL 字段类型的一些最终映射逻辑。函数列表中最后一个函数的输出可在管道解析器映射模板中用作 `$ctx.prev.result` 或 `$ctx.result`。

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

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

![\[GraphQL request flow diagram showing template processing and data source interactions.\]](http://docs.aws.amazon.com/zh_cn/appsync/latest/devguide/images/PipelineResolver.jpg)


1. 管道解析器的**之前**映射模板

1. 函数 1：函数请求映射模板

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

1. 函数 1：函数响应映射模板

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

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

1. 函数 2：函数响应映射模板

1. 管道解析器的**之后**映射模板

**注意**  
管道解析器执行流是单向的，并在解析器上静态定义。

#### 非常有用的 Apache Velocity 模板语言 (VTL) 实用程序
<a name="useful-apache-velocity-template-language-vtl-utilities"></a>

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

##### \$1ctx.stash
<a name="ctx-stash"></a>

存储区是一个在每个解析器和函数映射模板中提供的`Map`。同一存储实例通过单个解析程序生效。这意味着，您可以使用存储区来跨请求和响应映射模板以及管道解析器中的函数传递任意数据。存储区公开与 [Java 映射](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html)数据结构相同的方法。

##### \$1ctx.prev.result
<a name="ctx-prev-result"></a>

`$ctx.prev.result` 表示在管道解析器中执行的上一个操作的结果。

如果上一个操作是管道解析器的之前映射模板，则 `$ctx.prev.result` 表示模板评估的输出，并提供给管道中的第一个函数。如果上一个操作是第一个函数，则 `$ctx.prev.result` 表示第一个函数的输出，并且可供管道中的第二个函数使用。如果上一个操作是最后一个函数，则 `$ctx.prev.result` 表示最后一个函数的输出，并提供给管道解析器的之后映射模板。

##### \$1return(data: Object)
<a name="return-data-object"></a>

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

##### \$1return
<a name="return"></a>

这与 `#return(data: Object)` 相同，但返回 `null`。

##### \$1util.error
<a name="util-error"></a>

`$util.error` 实用工具对于引发字段错误很有用。在函数映射模板中使用 `$util.error` 会立即引发字段错误，从而阻止执行后续函数。有关更多详细信息和其他 `$util.error` 签名，请访问[解析器映射模板实用程序参考](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference)。

##### \$1util.appendError
<a name="util-appenderror"></a>

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

## 示例 模板
<a name="example-template"></a>

假设您在名为 `getPost(id:ID!)` 的字段上具有 DynamoDB 数据来源和**单位**解析器，该解析器使用以下 GraphQL 查询返回 `Post` 类型：

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

解析器模板应如下所示：

```
{
    "version" : "2018-05-29",
    "operation" : "GetItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    }
}
```

这会使用 `id` 输入参数值 `1` 替换 `${ctx.args.id}` 并生成以下 JSON：

```
{
    "version" : "2018-05-29",
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync 使用此模板生成有关与 DynamoDB 通信和获取数据（或根据需要执行其他操作）的指令。数据返回后， AWS AppSync 通过可选的可用于执行数据形状塑造或逻辑的响应映射模板以运行数据。例如，在我们从 DynamoDB 中获取结果时，它们可能如下所示：

```
{
        "id" : 1,
        "theTitle" : "AWS AppSync works offline!",
        "theContent-part1" : "It also has realtime functionality",
        "theContent-part2" : "using GraphQL"
}
```

您可以选择使用以下响应映射模板将两个字段联接成单一字段：

```
{
        "id" : $util.toJson($context.data.id),
        "title" : $util.toJson($context.data.theTitle),
        "content" : $util.toJson("${context.data.theContent-part1} ${context.data.theContent-part2}")
}
```

以下是将模板应用到数据后对设置数据形状的方式：

```
{
        "id" : 1,
        "title" : "AWS AppSync works offline!",
        "content" : "It also has realtime functionality using GraphQL"
}
```

此数据作为响应返回给客户端，如下所示：

```
{
        "data": {
                "getPost":      {
                        "id" : 1,
                        "title" : "AWS AppSync works offline!",
                        "content" : "It also has realtime functionality using GraphQL"
                }
        }
}
```

请注意，在大多数情况下，响应映射模板是简单的数据传递，主要由于您返回的是单个项目还是项目列表而不同。对于单个项目，传递：

```
$util.toJson($context.result)
```

对于列表，通常传递的是：

```
$util.toJson($context.result.items)
```

要查看单位解析器和管道解析器的更多示例，请参阅[解析器教程](tutorials.md#aws-appsync-tutorials)。

## 评估的映射模板反序列化规则
<a name="evaluated-mapping-template-deserialization-rules"></a>

映射模板评估结果为字符串。在中 AWS AppSync，输出字符串必须遵循 JSON 结构才有效。

此外，将强制执行以下反序列化规则。

### JSON 对象中不允许使用重复的键
<a name="duplicate-keys-are-not-allowed-in-json-objects"></a>

如果评估得出的映射模板字符串表示 JSON 对象或包含具有重复键的对象，则映射模板会返回以下错误消息：

 `Duplicate field 'aField' detected on Object. Duplicate JSON keys are not allowed.` 

已评估的请求映射模板中的重复键示例：

```
{
    "version": "2018-05-29",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "1",
        "field": "getPost" ## key 'field' has been redefined
    }
}
```

要修复此错误，请不要重新定义 JSON 对象中的键。

### JSON 对象中不允许使用尾随字符
<a name="trailing-characters-are-not-allowed-in-json-objects"></a>

如果评估得出的映射模板字符串表示 JSON 对象并包含尾随的无关字符，则映射模板会返回以下错误消息：

 `Trailing characters at the end of the JSON string are not allowed.` 

已评估的请求映射模板中的尾随字符示例：

```
{
    "version": "2018-05-29",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "1",
    }
}extraneouschars
```

要修复该错误，请确保评估的模板的评估结果严格为 JSON。

# AWS AppSync 解析器映射模板编程指南
<a name="resolver-mapping-template-reference-programming-guide"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

这是一本食谱式的编程教程，里面有 Apache Velocity 模板语言 (VTL)。 AWS AppSync如果您熟悉其他编程语言 JavaScript，例如 C 或 Java，则应该相当简单。

AWS AppSync 使用 VTL 将来自客户端的 GraphQL 请求转换为对您的数据源的请求。然后，它将这一过程反转，将数据来源响应转换回 GraphQL 响应。VTL 是一种逻辑模板语言，它使您能够使用以下技术在 Web 应用程序的标准 request/response 流程中同时操作请求和响应：
+ 新项目的默认值
+ 输入验证和格式化
+ 转换数据和设置数据形状
+ 遍历列表、映射和数组，从而提取值或更改值
+ 根据用户身份筛选/更改响应
+ 复杂的授权检查

例如，您可能希望在该服务中对 GraphQL 参数执行电话号码验证，或者在将输入参数存储到 DynamoDB 之前将其转换为大写。或者您可能希望客户端系统提供一个代码，作为 GraphQL 参数、JWT 令牌声明或 HTTP 标头的一部分，并且仅在该代码与列表中的特定字符串匹配时才利用数据做出响应。这些都是可以在 VTL 中 AWS AppSync执行的逻辑检查。

您可以通过 VTL 使用可能已很熟悉的编程技术应用逻辑。但是，它只能在标准 request/response 流程中运行，以确保您的GraphQL API可以随着用户群的增长而扩展。由于 AWS AppSync 还支持 AWS Lambda 作为解析器，所以如果你需要更大的灵活性，你可以用你选择的编程语言（Node.js、Python、Go、Java 等）编写 Lambda 函数。

## 设置
<a name="setup"></a>

学习语言时的一种常用技巧是打印出结果（例如，`console.log(variable)`在 JavaScript），看看会发生什么。在本教程中，我们将演示这一方法：创建一个简单的 GraphQL 架构，并将值的映射传递到 Lambda 函数中。Lambda 函数会输出这些值，并用这些值进行响应。这将使您能够了解 request/response 流程并了解不同的编程技术。

首先要创建以下 GraphQL 架构：

```
type Query {
    get(id: ID, meta: String): Thing
}

type Thing {
    id: ID!
    title: String!
    meta: String
}

schema {
    query: Query
}
```

现在使用 Node.js 作为语言创建以下 AWS Lambda 函数：

```
exports.handler = (event, context, callback) => {
    console.log('VTL details: ', event);
    callback(null, event);
};
```

在 AWS AppSync 控制台的 “**数据源**” 窗格中，将此 Lambda 函数添加为新的数据源。导航回控制台的**架构**页面，然后单击右侧的 `get(...):Thing` 查询旁边的**附加**按钮。对于请求模板，从 **Invoke and forward arguments (调用并转发参数)** 菜单中选择现有模板。对于响应模板，选择 **Return Lambda result (返回 Lambda 结果)**。

在一个位置打开您的 Lambda 函数的 Amazon CloudWatch 日志，然后从 AWS AppSync 控制台的 “**查询**” 选项卡中运行以下 GraphQL 查询：

```
query test {
  get(id:123 meta:"testing"){
    id
    meta
  }
}
```

GraphQL 响应应包含 `id:123` 和 `meta:testing`，因为 Lambda 函数将它们重复发送回来了。几秒钟后，您应该会在 CloudWatch 日志中看到一条包含这些详细信息的记录。

## 变量
<a name="variables"></a>

VTL 使用[引用](https://velocity.apache.org/engine/1.7/user-guide.html#references)存储或处理数据。VTL 中有三类引用：变量、属性和方法。变量前面有一个 `$` 符号，由 `#set` 指令创建：

```
#set($var = "a string")
```

变量存储的类型与您熟悉的其他语言类似，例如数字、字符串、数组、列表和映射。您可能已经注意到了，在 Lambda 解析器的默认请求模板中发送了 JSON 负载：

```
"payload": $util.toJson($context.arguments)
```

这里有几点需要注意——首先， AWS AppSync 为常见操作提供了几个便捷函数。在此示例中，`$util.toJson` 将一个变量转换为 JSON。第二，变量 `$context.arguments` 作为映射对象由一个 GraphQL 请求自动填充。您可以创建新映射，方法如下：

```
#set( $myMap = {
  "id": $context.arguments.id,
  "meta": "stuff",
  "upperMeta" : $context.arguments.meta.toUpperCase()
} )
```

现在您已创建一个名为 `$myMap` 的变量，它的键有 `id`、`meta` 和 `upperMeta`。这一操作也说明了几件事：
+  `id` 由 GraphQL 参数的键填充。这是 VTL 从客户端获取参数的常用方法。
+  `meta` 利用一个值进行硬编码，展示默认值。
+  `upperMeta` 使用 `meta` 方法转换 `.toUpperCase()` 参数。

将之前的代码加到请求模板的最上方，并更改 `payload` 以使用新的 `$myMap` 变量：

```
"payload": $util.toJson($myMap)
```

运行您的 Lambda 函数，您就可以在日志中 CloudWatch 看到响应变化以及这些数据。当您演练此教程的其余部分时，我们将继续填充 `$myMap`，这样您就可以运行类似的测试。

您也可以在变量中设置 *properties\$1*。它们可以是简单的字符串、数组或 JSON：

```
#set($myMap.myProperty = "ABC")
#set($myMap.arrProperty = ["Write", "Some", "GraphQL"])
#set($myMap.jsonProperty = {
    "AppSync" : "Offline and Realtime",
    "Cognito" : "AuthN and AuthZ"
})
```

### 无提示引用
<a name="quiet-references"></a>

由于 VTL 是一种模板化的语言，默认情况下，您进行的每次引用都会执行 `.toString()`。如果未定义引用，它会以字符串输出实际的引用表示形式。例如：

```
#set($myValue = 5)
##Prints '5'
$myValue

##Prints '$somethingelse'
$somethingelse
```

为了应对这一问题，VTL 有一种*无提示引用* 或*静默引用* 语法，告知模板引擎禁止此行为。该语法为 `$!{}`。例如，如果我们稍微改动一下之前的代码，使用 `$!{somethingelse}`，输出就会禁止：

```
#set($myValue = 5)
##Prints '5'
$myValue

##Nothing prints out
$!{somethingelse}
```

## 调用方法
<a name="calling-methods"></a>

在之前的示例中，我们向您演示了如何在创建变量的同时设置值。您还可以通过两个步骤在映射中添加数据，实现相同的目的，如下所示：

```
#set ($myMap = {})
#set ($myList = [])

##Nothing prints out
$!{myMap.put("id", "first value")}
##Prints "first value"
$!{myMap.put("id", "another value")}
##Prints true
$!{myList.add("something")}
```

 **但是**对于这种行为，您需要了解以下内容。虽然您可使用无提示引用表示法 `$!{}` 调用方法（如上所示），但它不会禁止所执行方法的返回值。因此在以上示例中我们会标注 `##Prints "first value"` 和 `##Prints true`。如果您要循环访问映射或列表，例如在已存在键的位置插入值，这样会引发错误。因为在评估时输出会在模板中添加意外字符串。

有时，可使用 `#set` 指令调用方法，并忽略变量来解决这一问题。例如：

```
#set ($myMap = {})
#set($discard = $myMap.put("id", "first value"))
```

你可以在模板中使用这种技术，因为它可以防止在模板中打印意想不到的字符串。 AWS AppSync 提供了另一种便捷函数，它以更简洁的表示法提供相同的行为。使用这一函数不必考虑这些具体的实施规范。您可以通过 `$util.quiet()` 或它的别名 `$util.qr()` 使用此函数。例如：

```
#set ($myMap = {})
#set ($myList = [])

##Nothing prints out
$util.quiet($myMap.put("id", "first value"))
##Nothing prints out
$util.qr($myList.add("something"))
```

## 字符串
<a name="strings"></a>

与许多编程语言一样，字符串有时可能较难处理，特别是当您希望通过变量生成字符串，情况更是如此。VTL 包含了许多处理字符串的常用功能。

假设您将数据作为字符串插入到 DynamoDB 等数据来源中，但它是通过变量（如 GraphQL 参数）填充的。字符串具有双引号，要在字符串中引用变量，您只需使用 `"${}"`（没有 `!`，就像 [quiet reference notation](https://velocity.apache.org/engine/1.7/user-guide.html#quiet-reference-notation) 中一样）。这类似于 [https://developer.mozilla 中的 JavaScript模板文字。 org/en-US/docs/Web/JavaScript/Reference/Template\$1literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) 

```
#set($firstname = "Jeff")
$!{myMap.put("Firstname", "${firstname}")}
```

您可以在 DynamoDB 请求模板中看到这种用法，例如，在使用来自 GraphQL 客户端的参数时的 `"author": { "S" : "${context.arguments.author}"}`，或者自动生成 ID 时的 `"id" : { "S" : "$util.autoId()"}`。这就意味着您可以引用变量，或方法的结果，在字符串内部填充数据。

您还可以使用 Java [String class](https://docs.oracle.com/javase/6/docs/api/java/lang/String.html) 的公共方法，例如提取子字符串：

```
#set($bigstring = "This is a long string, I want to pull out everything after the comma")
#set ($comma = $bigstring.indexOf(','))
#set ($comma = $comma +2)
#set ($substring = $bigstring.substring($comma))

$util.qr($myMap.put("substring", "${substring}"))
```

字符串联接也是一项常见的任务。您可以单独利用变量引用，或与静态值共同实现这一目的：

```
#set($s1 = "Hello")
#set($s2 = " World")

$util.qr($myMap.put("concat","$s1$s2"))
$util.qr($myMap.put("concat2","Second $s1 World"))
```

## Loops
<a name="loops"></a>

您已了解了如何创建变量及调用方法，现在可以在代码中添加一些逻辑了。与其他语言不同，VTL 只允许循环，迭代次数是提前确定的。Velocity 中没有 `do..while`。这一设计确保了评估过程始终会终止，并在执行 GraphQL 操作时提供了扩展边界。

使用 `#foreach` 可创建循环，需要您应用**循环变量**和**可遍历对象**，例如数组、列表、映射或集合。`#foreach` 循环的经典编程示例是遍历集合中的项目并将它们输出，因此在以下示例中，我们要把它们提取出来，并添加到映射中：

```
#set($start = 0)
#set($end = 5)
#set($range = [$start..$end])

#foreach($i in $range)
   ##$util.qr($myMap.put($i, "abc"))
   ##$util.qr($myMap.put($i, $i.toString()+"foo")) ##Concat variable with string
   $util.qr($myMap.put($i, "${i}foo"))     ##Reference a variable in a string with "${varname}"
#end
```

此示例展示了一些要点。第一，使用具有范围 `[..]` 运算符的变量，创建可遍历的对象。然后，每个项目由您可操作的 `$i` 变量引用。在上一示例中，您还会看到以双井号 `##` 表示的**注释**。该示例还展示了如何在键或值中使用循环变量，以及联接字符串的不同方法。

请注意，`$i` 是整数，因此您可以调用 `.toString()` 方法。对于 GraphQL 的 INT 类型，此方法很方便。

您还可以直接使用范围运算符，例如：

```
#foreach($item in [1..5])
    ...
#end
```

## 数组
<a name="arrays"></a>

目前，您已经可以处理映射了，但在 VTL 中数组也很常用。您也可以通过数组访问一些底层方法，例如 `.isEmpty()`、`.size()`、`.set()`、`.get()` 和 `.add()`，如下所示：

```
#set($array = [])
#set($idx = 0)

##adding elements
$util.qr($array.add("element in array"))
$util.qr($myMap.put("array", $array[$idx]))

##initialize array vals on create
#set($arr2 = [42, "a string", 21, "test"])

$util.qr($myMap.put("arr2", $arr2[$idx]))
$util.qr($myMap.put("isEmpty", $array.isEmpty()))  ##isEmpty == false
$util.qr($myMap.put("size", $array.size()))

##Get and set items in an array
$util.qr($myMap.put("set", $array.set(0, 'changing array value')))
$util.qr($myMap.put("get", $array.get(0)))
```

上一示例使用数组索引表示法检索具有 `arr2[$idx]` 的元素。你可以用类似的方式从 a Map/dictionary 中按名字查找：

```
#set($result = {
    "Author" : "Nadia",
    "Topic" : "GraphQL"
})

$util.qr($myMap.put("Author", $result["Author"]))
```

如果使用条件在响应模板中筛选数据来源中的结果，这种方法非常常用。

## 条件检查
<a name="conditional-checks"></a>

之前介绍 `#foreach` 的部分展示了一些示例，说明了如何利用 VTL 使用逻辑转换数据。您也可以应用条件检查以在运行时评估数据：

```
#if(!$array.isEmpty())
    $util.qr($myMap.put("ifCheck", "Array not empty"))
#else
    $util.qr($myMap.put("ifCheck", "Your array is empty"))
#end
```

以上对布尔表达式进行 `#if()` 检查的示例很棒，但您也可以将运算符和 `#elseif()` 用于分支：

```
#if ($arr2.size() == 0)
    $util.qr($myMap.put("elseIfCheck", "You forgot to put anything into this array!"))
#elseif ($arr2.size() == 1)
    $util.qr($myMap.put("elseIfCheck", "Good start but please add more stuff"))
#else
    $util.qr($myMap.put("elseIfCheck", "Good job!"))
#end
```

这两个示例展示了否定 (\$1) 和相等 (==)。我们还可以使用 \$1\$1、&&、>、<、>=、<= 和 \$1=。

```
#set($T = true)
#set($F = false)

#if ($T || $F)
  $util.qr($myMap.put("OR", "TRUE"))
#end

#if ($T && $F)
  $util.qr($myMap.put("AND", "TRUE"))
#end
```

 **注意：**在条件中只有 `Boolean.FALSE` 和 `null` 被视为 false。零 (0) 和空字符串 ("") 并不等同于 false。

## 运算符
<a name="operators"></a>

如果没有一些执行数学运算的运算符，那么编程语言就不完整。以下是一些入门示例：

```
#set($x = 5)
#set($y = 7)
#set($z = $x + $y)
#set($x-y = $x - $y)
#set($xy = $x * $y)
#set($xDIVy = $x / $y)
#set($xMODy = $x % $y)

$util.qr($myMap.put("z", $z))
$util.qr($myMap.put("x-y", $x-y))
$util.qr($myMap.put("x*y", $xy))
$util.qr($myMap.put("x/y", $xDIVy))
$util.qr($myMap.put("x|y", $xMODy))
```

### 结合使用循环和条件
<a name="loops-and-conditionals-together"></a>

在 VTL 中转换数据时，这非常常用。例如在从数据来源进行读或写的操作之前遍历对象，然后在执行操作之前进行检查。将之前的各部分中介绍的工具结合起来，您可以获得许多功能。一种非常好用的工具是，`#foreach` 会自动为每个项目提供 `.count`：

```
#foreach ($item in $arr2)
  #set($idx = "item" + $foreach.count)
  $util.qr($myMap.put($idx, $item))
#end
```

例如，可能您希望将不超过某一大小的映射中的值提取出来。结合使用计数、条件和 `#break` 语句即可实现这一目的：

```
#set($hashmap = {
  "DynamoDB" : "https://aws.amazon.com/dynamodb/",
  "Amplify" : "https://github.com/aws/aws-amplify",
  "DynamoDB2" : "https://aws.amazon.com/dynamodb/",
  "Amplify2" : "https://github.com/aws/aws-amplify"
})

#foreach ($key in $hashmap.keySet())
    #if($foreach.count > 2)
    #break
  #end
    $util.qr($myMap.put($key, $hashmap.get($key)))
#end
```

上一 `#foreach` 利用 `.keySet()` 进行遍历，您可将它用于映射。这样您就有权限获取 `$key`，并通过 `.get($key)` 引用值。来自中客户端的 GraphQL 参数以 AWS AppSync 映射形式存储。也可以通过 `.entrySet()` 循环访问这些参数，可通过它将键和值作为集进行访问，从而填充其他变量或执行复杂的条件检查，例如验证或转换输入：

```
#foreach( $entry in $context.arguments.entrySet() )
#if ($entry.key == "XYZ" && $entry.value == "BAD")
    #set($myvar = "...")
  #else
    #break
  #end
#end
```

其他常见的示例自动填充默认信息，例如，同步数据时的初始对象版本（在解决冲突时非常重要）或用于授权检查的对象的默认所有者 - Mary 创建了该博客文章，因此，代码为：

```
#set($myMap.owner ="Mary")
#set($myMap.defaultOwners = ["Admins", "Editors"])
```

## 上下文
<a name="context"></a>

您现在充分了解了如何在 AWS AppSync 解析器中使用 VTL 执行逻辑检查，让我们了解一下上下文对象：

```
$util.qr($myMap.put("context", $context))
```

其中包含您可以在 GraphQL 请求中访问的所有信息。有关详细解释，请参阅[上下文参考](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference)。

## 筛选
<a name="filtering"></a>

在此教程中，目前来自 Lambda 函数的所有信息已返回 GraphQL 查询，并进行了非常简单的 JSON 转换：

```
$util.toJson($context.result)
```

如果您要从数据来源获得响应，VTL 逻辑也同样强大，特别是对资源进行授权检查时更是如此。让我们演练一些示例。首先，尝试按如下方式更改响应模板：

```
#set($data = {
    "id" : "456",
    "meta" : "Valid Response"
})

$util.toJson($data)
```

无论您的 GraphQL 操作结果如何，硬编码值将返回客户端。把它稍做调整，用 Lambda 响应填充 `meta` 字段，我们在本教程前面学习条件时在 `elseIfCheck` 值中进行了相关设置：

```
#set($data = {
    "id" : "456"
})

#foreach($item in $context.result.entrySet())
    #if($item.key == "elseIfCheck")
        $util.qr($data.put("meta", $item.value))
    #end
#end

$util.toJson($data)
```

 `$context.result` 是映射，因此您可以使用 `entrySet()` 针对返回的键或值执行逻辑。由于 `$context.identity` 包含执行 GraphQL 操作的用户的相关信息，如果您从数据来源返回授权信息，那么您可以根据逻辑决定为用户返回全部、部分数据，或不返回数据。更改您的响应模板，使它与如下示例类似：

```
#if($context.result["id"] == 123)
    $util.toJson($context.result)
  #else
    $util.unauthorized()
#end
```

如果您运行 GraphQL 查询，数据将按正常情况返回。但如果您将 id 参数更改为 123 之外的值 (`query test { get(id:456 meta:"badrequest"){} }`)，将收到授权失败的消息。

您可以在[授权使用案例](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases)部分找到有关授权场景的更多示例。

### 模板示例
<a name="appendix-template-sample"></a>

如果您按照此教程的步骤执行，那么可能已逐步构建了此模板。如果您还没有这么做，我们将在下面提供模板，供您复制用于测试。

 **请求模板** 

```
#set( $myMap = {
  "id": $context.arguments.id,
  "meta": "stuff",
  "upperMeta" : "$context.arguments.meta.toUpperCase()"
} )

##This is how you would do it in two steps with a "quiet reference" and you can use it for invoking methods, such as .put() to add items to a Map
#set ($myMap2 = {})
$util.qr($myMap2.put("id", "first value"))

## Properties are created with a dot notation
#set($myMap.myProperty = "ABC")
#set($myMap.arrProperty = ["Write", "Some", "GraphQL"])
#set($myMap.jsonProperty = {
    "AppSync" : "Offline and Realtime",
    "Cognito" : "AuthN and AuthZ"
})

##When you are inside a string and just have ${} without ! it means stuff inside curly braces are a reference
#set($firstname = "Jeff")
$util.qr($myMap.put("Firstname", "${firstname}"))

#set($bigstring = "This is a long string, I want to pull out everything after the comma")
#set ($comma = $bigstring.indexOf(','))
#set ($comma = $comma +2)
#set ($substring = $bigstring.substring($comma))
$util.qr($myMap.put("substring", "${substring}"))

##Classic for-each loop over N items:
#set($start = 0)
#set($end = 5)
#set($range = [$start..$end])
#foreach($i in $range)          ##Can also use range operator directly like #foreach($item in [1...5])
   ##$util.qr($myMap.put($i, "abc"))
   ##$util.qr($myMap.put($i, $i.toString()+"foo")) ##Concat variable with string
   $util.qr($myMap.put($i, "${i}foo"))     ##Reference a variable in a string with "${varname)"
#end

##Operators don't work
#set($x = 5)
#set($y = 7)
#set($z = $x + $y)
#set($x-y = $x - $y)
#set($xy = $x * $y)
#set($xDIVy = $x / $y)
#set($xMODy = $x % $y)
$util.qr($myMap.put("z", $z))
$util.qr($myMap.put("x-y", $x-y))
$util.qr($myMap.put("x*y", $xy))
$util.qr($myMap.put("x/y", $xDIVy))
$util.qr($myMap.put("x|y", $xMODy))

##arrays
#set($array = ["first"])
#set($idx = 0)
$util.qr($myMap.put("array", $array[$idx]))
##initialize array vals on create
#set($arr2 = [42, "a string", 21, "test"])
$util.qr($myMap.put("arr2", $arr2[$idx]))
$util.qr($myMap.put("isEmpty", $array.isEmpty()))  ##Returns false
$util.qr($myMap.put("size", $array.size()))
##Get and set items in an array
$util.qr($myMap.put("set", $array.set(0, 'changing array value')))
$util.qr($myMap.put("get", $array.get(0)))

##Lookup by name from a Map/dictionary in a similar way:
#set($result = {
    "Author" : "Nadia",
    "Topic" : "GraphQL"
})
$util.qr($myMap.put("Author", $result["Author"]))


##Conditional examples
#if(!$array.isEmpty())
$util.qr($myMap.put("ifCheck", "Array not empty"))
#else
$util.qr($myMap.put("ifCheck", "Your array is empty"))
#end

#if ($arr2.size() == 0)
$util.qr($myMap.put("elseIfCheck", "You forgot to put anything into this array!"))
#elseif ($arr2.size() == 1)
$util.qr($myMap.put("elseIfCheck", "Good start but please add more stuff"))
#else
$util.qr($myMap.put("elseIfCheck", "Good job!"))
#end

##Above showed negation(!) and equality (==), we can also use OR, AND, >, <, >=, <=, and !=
#set($T = true)
#set($F = false)
#if ($T || $F)
  $util.qr($myMap.put("OR", "TRUE"))
#end

#if ($T && $F)
  $util.qr($myMap.put("AND", "TRUE"))
#end

##Using the foreach loop counter - $foreach.count
#foreach ($item in $arr2)
  #set($idx = "item" + $foreach.count)
  $util.qr($myMap.put($idx, $item))
#end

##Using a Map and plucking out keys/vals
#set($hashmap = {
    "DynamoDB" : "https://aws.amazon.com/dynamodb/",
    "Amplify" : "https://github.com/aws/aws-amplify",
    "DynamoDB2" : "https://aws.amazon.com/dynamodb/",
    "Amplify2" : "https://github.com/aws/aws-amplify"
})

#foreach ($key in $hashmap.keySet())
    #if($foreach.count > 2)
        #break
    #end
    $util.qr($myMap.put($key, $hashmap.get($key)))
#end

##concatenate strings
#set($s1 = "Hello")
#set($s2 = " World")
$util.qr($myMap.put("concat","$s1$s2"))
$util.qr($myMap.put("concat2","Second $s1 World"))

$util.qr($myMap.put("context", $context))

{
    "version" : "2017-02-28",
    "operation": "Invoke",
    "payload": $util.toJson($myMap)
}
```

 **响应模板** 

```
#set($data = {
"id" : "456"
})
#foreach($item in $context.result.entrySet())   ##$context.result is a MAP so we use entrySet()
    #if($item.key == "ifCheck")
        $util.qr($data.put("meta", "$item.value"))
    #end
#end

##Uncomment this out if you want to test and remove the below #if check
##$util.toJson($data)

#if($context.result["id"] == 123)
    $util.toJson($context.result)
  #else
    $util.unauthorized()
#end
```

# AWS AppSync 解析器映射模板上下文参考
<a name="resolver-context-reference"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

AWS AppSync 定义了一组用于处理解析器映射模板的变量和函数。这样，就可以更轻松地通过 GraphQL 对数据进行逻辑操作。本文档将介绍这些函数，并提供使用模板的示例。

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

`$context` 变量是一个映射，它保留进行解析器调用的所有上下文信息。它具有以下结构：

```
{
   "arguments" : { ... },
   "source" : { ... },
   "result" : { ... },
   "identity" : { ... },
   "request" : { ... },
   "info": { ... }
}
```

**注意**  
如果您尝试通过键访问 dictionary/map 条目（例如中的条目`context`）来检索该值，Velocity 模板语言 (VTL) 允许您直接使用该符号`<dictionary-element>.<key-name>`。但是，这可能不适用于所有情况，例如当键名称具有特殊字符时（例如，下划线“\$1”）。建议您始终使用 `<dictionary-element>.get("<key-name>")` 表示法。

`$context` 映射中每个字段的定义如下所示：

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

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

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

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

** `stash` **  
存储区是一个在每个解析器和函数映射模板中提供的映射。同一存储实例通过单个解析程序生效。这意味着，您可以使用存储区来跨请求和响应映射模板以及管道解析器中的函数传递任意数据。存储区公开与 [Java 映射](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html)数据结构相同的方法。

** `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)。

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

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

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

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

**`AWS_LAMBDA` 授权**  
`identity` 包含 `resolverContext` 密钥，其中包含为请求授权的 Lambda 函数返回的相同 `resolverContext` 内容。

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

```
{
    "accountId" : "string",
    "cognitoIdentityPoolId" : "string",
    "cognitoIdentityId" : "string",
    "sourceIp" : ["string"],
    "username" : "string", // IAM user principal
    "userArn" : "string",
    "cognitoIdentityAuthType" : "string", // authenticated/unauthenticated based on the identity type
    "cognitoIdentityAuthProvider" : "string" // the auth provider that was used to obtain the credentials
}
```

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

```
{
    "sub" : "uuid",
    "issuer" : "string",
    "username" : "string"
    "claims" : { ... },
    "sourceIp" : ["x.x.x.x"],
    "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"></a>

AWS AppSync 支持从客户端传递自定义标头，并使用在 GraphQL 解析器中访问它们。`$context.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
```

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

```
"custom": $util.dynamodb.toDynamoDBJson($context.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
```

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

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

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

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

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

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

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

```
{
    "fieldName": "string",
    "parentTypeName": "string",
    "variables": { ... },
    "selectionSetList": ["string"],
    "selectionSetGraphQL": "string"
}
```

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

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

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

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

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

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

**注意**  
默认情况下，在 `context.info` 上使用 `$utils.toJson()` 时，不会序列化 `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
  }
}
```

那么，在处理映射模板时可用的完整 `$context.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"
]
```

## 清理输入
<a name="sanitizing-inputs"></a>

应用程序必须对不可信的输入进行清理，以防止任何外部方在应用程序的预期用途之外使用该应用程序。由于 `$context` 包含 `$context.arguments`、`$context.identity`、`$context.result`、`$context.info.variables` 和 `$context.request.headers` 等属性中的用户输入，因此，务必谨慎在映射模板中清理它们的值。

由于映射模板代表 JSON，因此输入清理采用从表示用户输入的字符串转义 JSON 保留字符的形式。将 JSON 保留字符放入映射模板时，最佳做法是使用 `$util.toJson()` 实用程序从敏感字符串值转义 JSON 保留字符。

例如，在以下 Lambda 请求映射模板中，由于我们访问了不安全的客户输入字符串 (`$context.arguments.id`)，因此，我们使用 `$util.toJson()` 将其包装起来，以防止未转义的 JSON 字符破坏 JSON 模板。

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": $util.toJson($context.arguments.id)
    }
}
```

下面的映射模板与之相反，我们直接插入 `$context.arguments.id` 而不进行清理。这不适用于包含未转义引号或其他 JSON 保留字符的字符串，并且可能使您的模板很容易失败。

```
## DO NOT DO THIS
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "$context.arguments.id" ## Unsafe! Do not insert $context string values without escaping JSON characters.
    }
}
```

# AWS AppSync 解析器映射模板实用程序参考
<a name="resolver-util-reference"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

AWS AppSync 定义了一组实用程序，您可以在 GraphQL 解析器中使用这些实用程序来简化与数据源的交互。其中一些实用程序适用于任何数据源，例如生成 IDs 或时间戳。其他实用程序是某种类型的数据来源特定的。可以使用以下实用程序：
+  [\$1util 中的实用程序帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/utility-helpers-in-util.html)：\$1util 变量包含帮助您处理数据的常规实用程序方法。除非另行指定，否则所有实用程序均使用 UTF-8 字符集。
+ [ AppSync 指令](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-directives.html)- AppSync 公开指令以提高开发人员在 VTL 中编写时的生产力。
+  [\$1util.time 中的时间帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/time-helpers-in-util-time.html)：\$1util.time 变量包含的日期时间方法有助于生成时间截，在不同的日期时间格式之间进行转换，并解析日期时间字符串。日期时间格式的语法基于该语法 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)，您可以参考该语法以获取更多文档。
+ [\$1util.list 中的列表帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/list-helpers-in-util-list.html)：\$1util.list 包含一些方法以帮助执行常见的列表操作，例如在列表中删除或保留项目以用于筛选使用案例。
+  [\$1util.map 中的映射帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/utility-helpers-in-map.html)：\$1util.map 包含一些方法以帮助执行常见的映射操作，例如在映射中删除或保留项目以用于筛选使用案例。
+  [\$1util.dynamodb 中的 DynamoDB 帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb.html)：\$1util.dynamodb 包含一些帮助程序方法，可以更轻松地在 Amazon DynamoDB 中写入和读取数据，例如自动类型映射和格式设置。
+  [\$1util.rds 中的 Amazon RDS 帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/rds-helpers-in-util-rds.html)：\$1util.rds 包含一些帮助程序方法，可以删除结果输出中的无关数据以设置 RDS 操作格式。
+  [\$1util.http 中的 HTTP 帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/http-helpers-in-utils-http.html)：\$1util.http 实用程序提供一些帮助程序方法，可用于管理 HTTP 请求参数和添加响应标头。
+  [\$1util.xml 中的 XML 帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/xml-helpers-in-utils-xml.html)：\$1util.xml 包含一些帮助程序方法，可以更轻松地将 XML 响应转换为 JSON 或字典。
+  [\$1util.transform 中的转换帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/transformation-helpers-in-utils-transform.html)：\$1util.transform 包含一些帮助程序方法，可以更轻松地对数据来源执行复杂的操作，例如 DynamoDB 筛选操作。
+  [\$1util.math 中的数学帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/math-helpers-in-util-math.html)：\$1util.math 包含一些帮助进行常见数学运算的方法。
+  [\$1util.str 中的字符串帮助程序](https://docs.aws.amazon.com/appsync/latest/devguide/str-helpers-in-util-str.html)：\$1util.str 包含一些帮助执行常见字符串操作的方法。
+  [扩展程序](https://docs.aws.amazon.com/appsync/latest/devguide/extensions.html)：\$1extensions 包含一组在解析器中执行额外操作的方法。

# \$1util 中的实用程序帮助程序
<a name="utility-helpers-in-util"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

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

## JSON 解析实用程序
<a name="utility-helpers-in-json-parsing"></a>

### JSON 解析实用程序列表
<a name="utility-helpers-in-json-parsing-list"></a>

** **`$util.parseJson(String) : Object`** **  
获取“字符串化的”JSON 并返回结果的对象表示形式。

** **`$util.toJson(Object) : String`** **  
获取对象并返回该对象“字符串化的”JSON 表示形式。

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

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

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

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

** **`$util.base64Encode( byte[] ) : String`** **  
将输入编码为 base64 编码字符串。

** **`$util.base64Decode(String) : byte[]`** **  
对 base64 编码字符串中的数据进行解码。

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

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

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

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

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

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

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

** `$util.error(String)` **  
引发自定义错误。可以在请求或响应映射模板中使用该实用程序，以检测请求或调用结果的错误。

** `$util.error(String, String)` **  
引发自定义错误。可以在请求或响应映射模板中使用该实用程序，以检测请求或调用结果的错误。您还可以指定 `errorType`。

** `$util.error(String, String, Object)` **  
引发自定义错误。可以在请求或响应映射模板中使用该实用程序，以检测请求或调用结果的错误。您还可以指定 `errorType` 和 `data` 字段。将在 GraphQL 响应中 `data` 内部对应的 `error` 块中添加 `errors` 值。  
`data` 将根据查询选择集进行筛选。

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

** `$util.appendError(String)` **  
追加自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。与 `$util.error(String)` 不同，不会中断模板评估，因此，可以向调用方返回数据。

** `$util.appendError(String, String)` **  
追加自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。此外，还可指定 `errorType`。与 `$util.error(String, String)` 不同，不会中断模板评估，因此，可以向调用方返回数据。

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

** `$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-condition"></a>

### 条件验证实用程序列表
<a name="utility-helpers-in-condition-list"></a>

** `$util.validate(Boolean, String) : void` **  
如果条件为假，则 CustomTemplateException 使用指定的消息抛出 a。

** `$util.validate(Boolean, String, String) : void` **  
如果条件为 false，则 CustomTemplateException 使用指定的消息和错误类型抛出。

** `$util.validate(Boolean, String, String, Object) : void` **  
如果条件为 false，则抛出 a， CustomTemplateException 其中包含指定的消息和错误类型，以及要在响应中返回的数据。

## Null 行为实用程序
<a name="utility-helpers-in-null-behavior"></a>

### Null 行为实用程序列表
<a name="utility-helpers-in-null-behavior-list"></a>

** `$util.isNull(Object) : Boolean` **  
如果提供的对象为 null 则返回 true。

** `$util.isNullOrEmpty(String) : Boolean` **  
如果提供的数据为 null 或空字符串，则返回 true。否则返回 false。

** `$util.isNullOrBlank(String) : Boolean` **  
如果提供的数据为 null 或空白字符串，则返回 true。否则返回 false。

** `$util.defaultIfNull(Object, Object) : Object` **  
如果首个对象非 null，则返回它。否则返回第二个对象，作为“默认对象”。

** `$util.defaultIfNullOrEmpty(String, String) : String` **  
如果首个字符串非 null 也非空，则返回它。否则返回第二个字符串，作为“默认字符串”。

** `$util.defaultIfNullOrBlank(String, String) : String` **  
如果首个字符串非 null 也非空白，则返回它。否则返回第二个字符串，作为“默认字符串”。

## 模式匹配实用程序
<a name="utility-helpers-in-pattern-matching"></a>

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

** `$util.typeOf(Object) : String` **  
返回字符串，描述对象的类型。支持的类型标识为："Null"、"Number"、"String"、"Map"、"List"、"Boolean"。如果无法识别类型，则返回 "Object" 类型。

** `$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() : String` **  
返回描述请求使用的多重身份验证类型的字符串，即，返回“IAM Authorization”、“User Pool Authorization”、“Open ID Connect Authorization”或“API Key Authorization”。

## 对象验证实用程序
<a name="utility-helpers-in-object-validation"></a>

### 对象验证实用程序列表
<a name="utility-helpers-in-object-validation-list"></a>

** `$util.isString(Object) : Boolean` **  
如果对象是字符串，则返回 true。

** `$util.isNumber(Object) : Boolean` **  
如果对象是数字，则返回 true。

** `$util.isBoolean(Object) : Boolean` **  
如果对象是布尔值，则返回 true。

** `$util.isList(Object) : Boolean` **  
如果对象是列表，则返回 true。

** `$util.isMap(Object) : Boolean` **  
如果对象是映射，则返回 true。

## CloudWatch 日志工具
<a name="utility-helpers-in-logging"></a>

### CloudWatch 日志实用程序列表
<a name="utility-helpers-in-cloudwatch-logs"></a>

**`$util.log.info(Object) : Void`**  
如果在 API 上启用了请求级别和字段级日志 CloudWatch 记录，则将所提供对象的字符串表示形式记录到请求的日志流`ALL``INFO`中。`DEBUG`

**`$util.log.info(String, Object...) : Void`**  
在 API 上启用请求级和字段级日志记录时，将所提供对象的字符串表示形式 CloudWatch 记录到请求的日志流中。`ALL`该实用程序按顺序将第一个输入格式字符串中由“\$1\$1”指示的所有变量替换为提供的对象的字符串表示形式。

**`$util.log.debug(Object) : Void`**  
当使用日志级别`ALL`或 `DEBUG` API 启用请求级和字段级日志 CloudWatch 记录时，将所提供对象的字符串表示形式记录到请求的日志流中。

**`$util.log.debug(String, Object...) : Void`**  
在 API 上使用日志级别`DEBUG`或日志级别启用字段级日志 CloudWatch 记录时，将所提供对象的字符串表示形式记录到请求的日志流中。`ALL`该实用程序按顺序将第一个输入格式字符串中由“\$1\$1”指示的所有变量替换为提供的对象的字符串表示形式。

**`$util.log.error(Object) : Void`**  
在 API 上启用**任何**日志级别（`ALL`、、`INFO`等）的字段级 CloudWatch 日志记录时，将所提供对象的字符串表示形式记录到请求的日志流中。`DEBUG`

**`$util.log.error(String, Object...) : Void`**  
在 API 上使用日志级别`ERROR`或日志级别启用字段级日志 CloudWatch 记录时，将所提供对象的字符串表示形式记录到请求的日志流中。`ALL`该实用程序按顺序将第一个输入格式字符串中由“\$1\$1”指示的所有变量替换为提供的对象的字符串表示形式。

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

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

****`$util.qr()`** 和 `$util.quiet()` **  
运行 VTL 语句，同时禁止返回值。这对于在不使用临时占位符的情况下运行方法非常有用，例如，在映射中添加项目。例如：  

```
#set ($myMap = {})
#set($discard = $myMap.put("id", "first value"))
```
变为：  

```
#set ($myMap = {})
$util.qr($myMap.put("id", "first value"))
```  
** `$util.escapeJavaScript(String) : String` **  
以转义字符串的形式返回输入 JavaScript 字符串。  
** `$util.urlEncode(String) : String` **  
将输入字符串作为 `application/x-www-form-urlencoded` 编码字符串返回。  
** `$util.urlDecode(String) : String` **  
将 `application/x-www-form-urlencoded` 编码的字符串解码回未编码的形式。  
** `$util.base64Encode( byte[] ) : String` **  
将输入编码为 base64 编码字符串。  
** `$util.base64Decode(String) : byte[]` **  
对 base64 编码字符串中的数据进行解码。  
** `$util.parseJson(String) : Object` **  
获取“字符串化的”JSON 并返回结果的对象表示形式。  
** `$util.toJson(Object) : String` **  
获取对象并返回该对象“字符串化的”JSON 表示形式。  
** `$util.autoId() : String` **  
返回 128 位随机生成的 UUID。  
****`$util.autoUlid() : String`****  
返回一个 128 位随机生成的 ULID（可按字典排序的通用唯一标识符）。  
****`$util.autoKsuid() : String`****  
返回一个 128 位随机生成的 KSUID（K 可排序唯一标识符），它使用 Base62 编码为长度为 27 的字符串。  
** `$util.unauthorized()` **  
针对被解析的字段引发 `Unauthorized`。可以在请求或响应映射模板中使用该实用程序，以确定是否允许调用方解析该字段。  
** `$util.error(String)` **  
引发自定义错误。可以在请求或响应映射模板中使用该实用程序，以检测请求或调用结果的错误。  
** `$util.error(String, String)` **  
引发自定义错误。可以在请求或响应映射模板中使用该实用程序，以检测请求或调用结果的错误。您还可以指定 `errorType`。  
** `$util.error(String, String, Object)` **  
引发自定义错误。可以在请求或响应映射模板中使用该实用程序，以检测请求或调用结果的错误。您还可以指定 `errorType` 和 `data` 字段。将在 GraphQL 响应中 `data` 内部对应的 `error` 块中添加 `errors` 值。**注意**：将根据查询选择集筛选 `data`。  
** `$util.error(String, String, Object, Object)` **  
引发自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。此外，还可指定 `errorType`、`data` 和 `errorInfo` 字段。将在 GraphQL 响应中 `data` 内部对应的 `error` 块中添加 `errors` 值。**注意**：将根据查询选择集筛选 `data`。将在 GraphQL 响应中 `errorInfo` 内部对应的 `error` 块中添加 `errors` 值。**注意**：`errorInfo`不会**根据查询选择集筛选 **。  
** `$util.appendError(String)` **  
追加自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。与 `$util.error(String)` 不同，不会中断模板评估，因此，可以向调用方返回数据。  
** `$util.appendError(String, String)` **  
追加自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。此外，还可指定 `errorType`。与 `$util.error(String, String)` 不同，不会中断模板评估，因此，可以向调用方返回数据。  
** `$util.appendError(String, String, Object)` **  
追加自定义错误。如果模板检测到请求或调用结果的错误，可用于请求或响应映射模板中。此外，还可指定 `errorType` 和 `data` 字段。与 `$util.error(String, String, Object)` 不同，不会中断模板评估，因此，可以向调用方返回数据。将在 GraphQL 响应中 `data` 内部对应的 `error` 块中添加 `errors` 值。**注意**：将根据查询选择集筛选 `data`。  
** `$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`不会**根据查询选择集筛选 **。  
** `$util.validate(Boolean, String) : void` **  
如果条件为假，则 CustomTemplateException使用指定的消息抛出 a。  
** `$util.validate(Boolean, String, String) : void` **  
如果条件为 false，则 CustomTemplateException使用指定的消息和错误类型抛出。  
** `$util.validate(Boolean, String, String, Object) : void` **  
如果条件为 false，则抛出 a， CustomTemplateException其中包含指定的消息和错误类型，以及要在响应中返回的数据。  
** `$util.isNull(Object) : Boolean` **  
如果提供的对象为 null 则返回 true。  
** `$util.isNullOrEmpty(String) : Boolean` **  
如果提供的数据为 null 或空字符串，则返回 true。否则返回 false。  
** `$util.isNullOrBlank(String) : Boolean` **  
如果提供的数据为 null 或空白字符串，则返回 true。否则返回 false。  
** `$util.defaultIfNull(Object, Object) : Object` **  
如果首个对象非 null，则返回它。否则返回第二个对象，作为“默认对象”。  
** `$util.defaultIfNullOrEmpty(String, String) : String` **  
如果首个字符串非 null 也非空，则返回它。否则返回第二个字符串，作为“默认字符串”。  
** `$util.defaultIfNullOrBlank(String, String) : String` **  
如果首个字符串非 null 也非空白，则返回它。否则返回第二个字符串，作为“默认字符串”。  
** `$util.isString(Object) : Boolean` **  
如果对象是字符串，则返回 true。  
** `$util.isNumber(Object) : Boolean` **  
如果对象是数字，则返回 true。  
** `$util.isBoolean(Object) : Boolean` **  
如果对象是布尔值，则返回 true。  
** `$util.isList(Object) : Boolean` **  
如果对象是列表，则返回 true。  
** `$util.isMap(Object) : Boolean` **  
如果对象是映射，则返回 true。  
** `$util.typeOf(Object) : String` **  
返回字符串，描述对象的类型。支持的类型标识为："Null"、"Number"、"String"、"Map"、"List"、"Boolean"。如果无法识别类型，则返回 "Object" 类型。  
** `$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() : String` **  
返回描述请求使用的多重身份验证类型的字符串，即，返回“IAM Authorization”、“User Pool Authorization”、“Open ID Connect Authorization”或“API Key Authorization”。  
****`$util.log.info(Object) : Void`****  
在 API 上启用请求级和字段级日志记录时，将所提供对象的字符串表示形式 CloudWatch记录到请求的日志流中。`ALL`  
****`$util.log.info(String, Object...) : Void`****  
在 API 上启用请求级和字段级日志记录时，将所提供对象的字符串表示形式 CloudWatch记录到请求的日志流中。`ALL`该实用程序按顺序将第一个输入格式字符串中由“\$1\$1”指示的所有变量替换为提供的对象的字符串表示形式。  
****`$util.log.error(Object) : Void`****  
在 API 上使用日志级别`ERROR`或日志级别启用字段级日志 CloudWatch 记录时，将所提供对象的字符串表示形式记录到请求的日志流中。`ALL`  
****`$util.log.error(String, Object...) : Void`****  
在 API 上使用日志级别`ERROR`或日志级别启用字段级日志 CloudWatch 记录时，将所提供对象的字符串表示形式记录到请求的日志流中。`ALL`该实用程序按顺序将第一个输入格式字符串中由“\$1\$1”指示的所有变量替换为提供的对象的字符串表示形式。

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

## 解析器授权
<a name="utility-helpers-in-resolver-auth"></a>

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

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

# AWS AppSync 指令
<a name="aws-appsync-directives"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

AWS AppSync 公开指令以提高开发人员在 VTL 中编写时的生产力。

## 指令实用程序
<a name="utility-helpers-in-directives"></a>

****`#return(Object)`****  
`#return(Object)` 允许您提前从任何映射模板返回。`#return(Object)` 类似于编程语言中的 *return* 关键字，因为它从最近的逻辑范围块返回。在解析器映射模板内使用 `#return(Object)` 将从解析器返回。此外，从函数映射模板中使用 `#return(Object)` 将从该函数返回，并继续运行到管道中的下一个函数或解析器响应映射模板。

****`#return`****  
`#return` 指令具有与 `#return(Object)` 相同的行为，但返回 `null`。

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

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

`$util.time` 变量包含的日期时间方法有助于生成时间截，在不同的日期时间格式之间进行转换，并解析日期时间字符串。日期时间格式的语法基于该语法 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)，您可以参考该语法以获取更多文档。我们在下面提供了一些示例以及可用方法和描述列表。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

## 单独函数示例
<a name="standalone-function-examples"></a>

```
$util.time.nowISO8601()                                            : 2018-02-06T19:01:35.749Z
$util.time.nowEpochSeconds()                                       : 1517943695
$util.time.nowEpochMilliSeconds()                                  : 1517943695750
$util.time.nowFormatted("yyyy-MM-dd HH:mm:ssZ")                    : 2018-02-06 19:01:35+0000
$util.time.nowFormatted("yyyy-MM-dd HH:mm:ssZ", "+08:00")          : 2018-02-07 03:01:35+0800
$util.time.nowFormatted("yyyy-MM-dd HH:mm:ssZ", "Australia/Perth") : 2018-02-07 03:01:35+0800
```

## 转换示例
<a name="conversion-examples"></a>

```
#set( $nowEpochMillis = 1517943695758 )
$util.time.epochMilliSecondsToSeconds($nowEpochMillis)                                     : 1517943695
$util.time.epochMilliSecondsToISO8601($nowEpochMillis)                                     : 2018-02-06T19:01:35.758Z
$util.time.epochMilliSecondsToFormatted($nowEpochMillis, "yyyy-MM-dd HH:mm:ssZ")           : 2018-02-06 19:01:35+0000
$util.time.epochMilliSecondsToFormatted($nowEpochMillis, "yyyy-MM-dd HH:mm:ssZ", "+08:00") : 2018-02-07 03:01:35+0800
```

## 解析示例
<a name="parsing-examples"></a>

```
$util.time.parseISO8601ToEpochMilliSeconds("2018-02-01T17:21:05.180+08:00")                          : 1517476865180
$util.time.parseFormattedToEpochMilliSeconds("2018-02-02 01:19:22+0800", "yyyy-MM-dd HH:mm:ssZ")     : 1517505562000
$util.time.parseFormattedToEpochMilliSeconds("2018-02-02 01:19:22", "yyyy-MM-dd HH:mm:ss", "+08:00") : 1517505562000
```

## 使用 AWS AppSync 已定义的标量
<a name="usage-with-aws-scalars"></a>

以下格式与 `AWSDate`、`AWSDateTime` 和 `AWSTime` 兼容。

```
$util.time.nowFormatted("yyyy-MM-dd[XXX]", "-07:00:30")               : 2018-07-11-07:00
$util.time.nowFormatted("yyyy-MM-dd'T'HH:mm:ss[XXXXX]", "-07:00:30")  : 2018-07-11T15:14:15-07:00:30
```

# \$1util.list 中的列表帮助程序
<a name="list-helpers-in-util-list"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

`$util.list` 包含一些方法以帮助执行常见的列表操作，例如在列表中删除或保留项目以用于筛选使用案例。

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

** `$util.list.copyAndRetainAll(List, List) : List` **  
制作第一个参数中提供的列表的浅副本，同时仅保留第二个参数中指定的项目（如果存在）。所有其他项目将从副本中移除。

** `$util.list.copyAndRemoveAll(List, List) : List` **  
制作第一个参数中提供的列表的浅副本，同时删除在第二个参数中指定项目的任何项目（如果存在）。所有其他项目将保留在副本中。

** `$util.list.sortList(List, Boolean, String) : List` **  
对第一个参数中提供的对象列表进行排序。如果第二个参数为 true，则列表按降序进行排序；如果第二个参数为 false，则列表按升序进行排序。第三个参数是用于对自定义对象列表进行排序的属性的字符串名称。如果它只是字符串、整数、浮点数或双精度数列表，则第三个参数可能是任何随机字符串。如果所有对象不是来自同一个类，则返回原始列表。仅支持最多包含 1000 个对象的列表。以下是该实用程序的用法示例：  

```
 INPUT:      $util.list.sortList([{"description":"youngest", "age":5},{"description":"middle", "age":45}, {"description":"oldest", "age":85}], false, "description")
 OUTPUT:     [{"description":"middle", "age":45}, {"description":"oldest", "age":85}, {"description":"youngest", "age":5}]
```

# \$1util.map 中的映射帮助程序
<a name="utility-helpers-in-map"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

 `$util.map` 包含一些方法以帮助执行常见的映射操作，例如在映射中删除或保留项目以用于筛选使用案例。

## 映射实用程序
<a name="utility-helpers-in-map-list"></a>

** `$util.map.copyAndRetainAllKeys(Map, List) : Map` **  
制作第一个映射的浅副本，同时仅保留列表中指定的键（如果存在）。所有其他键将从副本中移除。

** `$util.map.copyAndRemoveAllKeys(Map, List) : Map` **  
制作第一个映射的浅副本，同时删除在列表中指定键的任何条目（如果存在）。所有其他键将保留在副本中。

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

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

`$util.dynamodb` 包含一些帮助程序方法，可以更轻松地在 Amazon DynamoDB 中写入和读取数据，例如自动类型映射和格式设置。这些方法旨在自动将基元类型和列表映射到正确的 DynamoDB 输入格式，即格式 `{ "TYPE" : VALUE }` 的 `Map`。

例如，以前用于在 DynamoDB 中创建新项目的请求映射模板可能如下所示：

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "id" : { "S" : "$util.autoId()" }
    },
    "attributeValues" : {
         "title" : { "S" : $util.toJson($ctx.args.title) },
         "author" : { "S" : $util.toJson($ctx.args.author) },
         "version" : { "N", $util.toJson($ctx.args.version) }
    }
}
```

如果我们想为对象添加字段，则必须在架构中更新 GraphQL 查询，还要更新请求映射模板。不过，我们现在可以重构请求映射模板，以使其自动选取在架构中添加的新字段，并使用正确的类型将其添加到 DynamoDB 中：

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

在上一示例中，我们使用 `$util.dynamodb.toDynamoDBJson(...)` 帮助程序自动获取生成的 ID，并将其转换为字符串属性的 DynamoDB 表示形式。然后，我们获取所有参数，将其转换为其 DynamoDB 表示形式，并输出到模板中的 `attributeValues` 字段。

每个帮助程序均有两个版本：一个版本返回对象（例如 `$util.dynamodb.toString(...)`）；一个版本将对象返回为 JSON 字符串（例如 `$util.dynamodb.toStringJson(...)`）。在上一示例中，我们使用了将数据返回为 JSON 字符串的版本。如果您希望在模板中使用对象之前处理对象，可以选择返回对象，如下所示：

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "id" : $util.dynamodb.toDynamoDBJson($util.autoId())
    },

    #set( $myFoo = $util.dynamodb.toMapValues($ctx.args) )
    #set( $myFoo.version = $util.dynamodb.toNumber(1) )
    #set( $myFoo.timestamp = $util.dynamodb.toString($util.time.nowISO8601()))

    "attributeValues" : $util.toJson($myFoo)
}
```

在上一示例中，我们将转换的参数作为映射返回，而不是 JSON 字符串；并在使用 `version` 最终输出到模板中的 `timestamp` 字段之前添加了 `attributeValues` 和 `$util.toJson(...)` 字段。

每个帮助程序的 JSON 版本等效于在 `$util.toJson(...)` 中包装非 JSON 版本。例如，以下语句是完全相同的：

```
$util.toStringJson("Hello, World!")
$util.toJson($util.toString("Hello, World!"))
```

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

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

** `$util.dynamodb.toDynamoDB(Object) : Map` **  
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" }
                       ]
                   }
               }
           }
```

****`$util.dynamodb.toDynamoDBJson(Object) : String`** **  
与 `$util.dynamodb.toDynamoDB(Object) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

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

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

** `$util.dynamodb.toStringJson(String) : Map` **  
与 `$util.dynamodb.toString(String) : String` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

** `$util.dynamodb.toStringSetJson(List<String>) : String` **  
与 `$util.dynamodb.toStringSet(List<String>) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

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

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

** `$util.dynamodb.toNumberJson(Number) : String` **  
与 `$util.dynamodb.toNumber(Number) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

** `$util.dynamodb.toNumberSetJson(List<Number>) : String` **  
与 `$util.dynamodb.toNumberSet(List<Number>) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

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

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

** `$util.dynamodb.toBinaryJson(String) : String` **  
与 `$util.dynamodb.toBinary(String) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

** `$util.dynamodb.toBinarySetJson(List<String>) : String` **  
与 `$util.dynamodb.toBinarySet(List<String>) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

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

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

** `$util.dynamodb.toBooleanJson(Boolean) : String` **  
与 `$util.dynamodb.toBoolean(Boolean) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

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

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

** `$util.dynamodb.toNullJson() : String` **  
与 `$util.dynamodb.toNull() : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

****`$util.dynamodb.toList(List) : Map`** **  
将对象列表转换为 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" }
                       }
                   }
               ]
           }
```

** `$util.dynamodb.toListJson(List) : String` **  
与 `$util.dynamodb.toList(List) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

** `$util.dynamodb.toMap(Map) : 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.toMapJson(Map) : String` **  
与 `$util.dynamodb.toMap(Map) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

** `$util.dynamodb.toMapValues(Map) : 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) : Map` 略有不同，因为它仅返回 DynamoDB 属性值内容，而不返回整个属性值本身。例如，以下语句是完全相同的：  

```
$util.dynamodb.toMapValues($map)
$util.dynamodb.toMap($map).get("M")
```

** `$util.dynamodb.toMapValuesJson(Map) : String` **  
与 `$util.dynamodb.toMapValues(Map) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

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

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

** `$util.dynamodb.toS3ObjectJson(String key, String bucket, String region) : String` **  
与 `$util.dynamodb.toS3Object(String key, String bucket, String region) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

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

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

** `$util.dynamodb.toS3ObjectJson(String key, String bucket, String region, String version) : String` **  
与 `$util.dynamodb.toS3Object(String key, String bucket, String region, String version) : Map` 相同，但以 JSON 编码字符串形式返回 DynamoDB 属性值。

** `$util.dynamodb.fromS3ObjectJson(String) : Map` **  
接受 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" }
```

# \$1util.rds 中的 Amazon RDS 帮助程序
<a name="rds-helpers-in-util-rds"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

`$util.rds` 包含一些帮助程序方法，可以删除结果输出中的无关数据以设置 Amazon RDS 操作格式。

## \$1util.rds 实用程序列表
<a name="rds-helpers-in-util-rds-list"></a>

****`$util.rds.toJsonString(String serializedSQLResult): String`****  
将字符串化的原始 Amazon Relational Database Service (Amazon RDS) 数据 API 操作结果格式转换为更简洁的字符串以返回 `String`。返回的字符串是结果集的序列化 SQL 记录列表。每条记录均表示为一个键-值对集合。键是对应的列名称。  
如果输入中的相应语句是导致变更的 SQL 查询（例如 INSERT、UPDATE、DELETE），则返回空列表。例如，查询 `select * from Books limit 2` 提供 Amazon RDS 数据操作的原始结果：  

```
{
    "sqlStatementResults": [
        {
            "numberOfRecordsUpdated": 0,
            "records": [
                [
                    {
                        "stringValue": "Mark Twain"
                    },
                    {
                        "stringValue": "Adventures of Huckleberry Finn"
                    },
                    {
                        "stringValue": "978-1948132817"
                    }
                ],
                [
                    {
                        "stringValue": "Jack London"
                    },
                    {
                        "stringValue": "The Call of the Wild"
                    },
                    {
                        "stringValue": "978-1948132275"
                    }
                  ]
            ],
            "columnMetadata": [
                {
                    "isSigned": false,
                    "isCurrency": false,
                    "label": "author",
                    "precision": 200,
                    "typeName": "VARCHAR",
                    "scale": 0,
                    "isAutoIncrement": false,
                    "isCaseSensitive": false,
                    "schemaName": "",
                    "tableName": "Books",
                    "type": 12,
                    "nullable": 0,
                    "arrayBaseColumnType": 0,
                    "name": "author"
                },
                {
                    "isSigned": false,
                    "isCurrency": false,
                    "label": "title",
                    "precision": 200,
                    "typeName": "VARCHAR",
                    "scale": 0,
                    "isAutoIncrement": false,
                    "isCaseSensitive": false,
                    "schemaName": "",
                    "tableName": "Books",
                    "type": 12,
                    "nullable": 0,
                    "arrayBaseColumnType": 0,
                    "name": "title"
                },
                {
                    "isSigned": false,
                    "isCurrency": false,
                    "label": "ISBN-13",
                    "precision": 15,
                    "typeName": "VARCHAR",
                    "scale": 0,
                    "isAutoIncrement": false,
                    "isCaseSensitive": false,
                    "schemaName": "",
                    "tableName": "Books",
                    "type": 12,
                    "nullable": 0,
                    "arrayBaseColumnType": 0,
                    "name": "ISBN-13"
                }
            ]
        }
    ]
}
```
`util.rds.toJsonString` 是：  

```
[
  {
    "author": "Mark Twain",
    "title": "Adventures of Huckleberry Finn",
    "ISBN-13": "978-1948132817"
  },
  {
    "author": "Jack London",
    "title": "The Call of the Wild",
    "ISBN-13": "978-1948132275"
  },
]
```

****`$util.rds.toJsonObject(String serializedSQLResult): Object`****  
这与 `util.rds.toJsonString` 相同，但结果是 JSON `Object`。

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

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

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

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

** `$util.http.copyHeaders(Map) : Map` **  
从映射中复制标头，不包括以下受限制的 HTTP 标头：  
+ transfer-encoding
+ connection
+ host
+ expect
+ keep-alive
+ upgrade
+ proxy-authenticate
+ proxy-authorization
+ te
+ content-length
您可以使用此实用程序将请求标头转发到下游 HTTP 端点。  

```
{
    ...
    "params": {
        ...
        "headers": $util.http.copyHeaders($ctx.request.headers),
        ...
    },
    ...
}
```

**\$1util.http。 addResponseHeader（字符串、对象）**  
添加单个自定义标头，其中包含响应的名称 (`String`) 和值 (`Object`)。适用以下限制：  
+ 除了 `copyHeaders(Map)` 的受限制标头列表外，标头名称不能与以下列出的任何名称相同：
  + 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 {}
}
```

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

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

`$util.xml` 包含一些帮助程序方法，可以更轻松地将 XML 响应转换为 JSON 或字典。

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

****`$util.xml.toMap(String) : Map`****  
将 XML 字符串转换为字典。  

```
Input:

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

Output (JSON representation):

{
  "posts":{
    "post":{
      "id":1,
      "title":"Getting started with GraphQL"
    }
  }
}


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 AWS AppSync</title>
</post>
</posts>

Output (JSON representation):

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

****`$util.xml.toJsonString(String) : String`****  
将 XML 字符串转换为 JSON 字符串。这与 *toMap* 类似，只不过输出是字符串。如果您要直接转换 XML 响应并将其从 HTTP 对象返回到 JSON，这非常有用。

****`$util.xml.toJsonString(String, Boolean) : String`****  
使用可选的布尔值参数将 XML 字符串转换为 JSON 字符串，以确定您是否要对 JSON 进行字符串编码。

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

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

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

## 转换帮助程序
<a name="transformation-helpers-conversions"></a>

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

****`$util.transform.toDynamoDBFilterExpression(Map) : Map`****  
将输入字符串转换为筛选条件表达式以用于 DynamoDB。  

```
Input:

$util.transform.toDynamoDBFilterExpression({
    "title":{
      "contains":"Hello World"
    }
  })

Output:

{
    "expression" : "contains(#title, :title_contains)"
    "expressionNames" : {
        "#title" : "title",
    },
    "expressionValues" : {
        ":title_contains" : { "S" : "Hello World" }
    },
}
```

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

```
Input:

$util.transform.toElasticsearchQueryDSL({
    "upvotes":{
        "ne":15,
        "range":[
            10,
            20
        ]
    },
    "title":{
        "eq":"hihihi",
        "wildcard":"h*i"
    }
  })

Output:
{
    "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。

## 转换帮助程序订阅筛选条件
<a name="transformation-helpers-conversions-subscription-filters"></a>

### 转换帮助程序订阅筛选条件实用程序列表
<a name="transformation-helpers-in-utils-transform-list"></a>

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

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

****`$util.transform.toSubscriptionFilter(Map, List, Map) : Map`****  
将 `Map` 输入对象转换为 `SubscriptionFilter` 表达式对象。`$util.transform.toSubscriptionFilter` 方法用作 `$extensions.setSubscriptionFilter()` 扩展的输入。有关更多信息，请参阅[扩展](https://docs.aws.amazon.com/appsync/latest/devguide/extensions)。  
第一个参数是转换为 `SubscriptionFilter` 表达式对象的 `Map` 输入对象，第二个参数是在第一个 `Map` 输入对象中忽略的字段名称 `List`，第三个参数是构建 `SubscriptionFilter` 表达式对象时包含的严格规则 `Map` 输入对象。这些严格规则包含在 `SubscriptionFilter` 表达式对象中，以便至少满足其中的一个规则才能通过订阅筛选条件。

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

下表介绍了如何定义以下实用程序的参数：
+ `$util.transform.toSubscriptionFilter(Map) : Map`
+ `$util.transform.toSubscriptionFilter(Map, List) : Map`
+ `$util.transform.toSubscriptionFilter(Map, List, Map) : Map`

------
#### [ 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"
        }
      ]
    }
  ]
}
```

------

# \$1util.math 中的数学帮助程序
<a name="math-helpers-in-util-math"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

 `$util.math` 包含一些方法以帮助进行常见的数学运算。

## \$1util.math 实用程序列表
<a name="math-helpers-in-util-math-list"></a>

** `$util.math.roundNum(Double) : Integer` **  
获取一个双精度值，并将其四舍五入到最接近的整数。

** `$util.math.minVal(Double, Double) : Double` **  
获取两个双精度值，并返回两个双精度值之间的最小值。

** `$util.math.maxVal(Double, Double) : Double` **  
获取两个双精度值，并返回两个双精度值之间的最大值。

** `$util.math.randomDouble() : Double` **  
返回 0 到 1 之间的随机双精度值。  
不应将该函数用于任何需要高熵随机性的场合（例如加密）。

** `$util.math.randomWithinRange(Integer, Integer) : Integer` **  
返回指定范围内的随机整数值，第一个参数指定范围的下限值，第二个参数指定范围的上限值。  
不应将该函数用于任何需要高熵随机性的场合（例如加密）。

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

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

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

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

** `$util.str.toUpper(String) : String` **  
获取一个字符串，并将其转换为完全大写。

** `$util.str.toLower(String) : String` **  
获取一个字符串，并将其转换为完全小写。

** `$util.str.toReplace(String, String, String) : String` **  
将字符串中的子字符串替换为另一个字符串。第一个参数指定要执行替换操作的字符串。第二个参数指定要替换的子字符串。第三个参数指定要替换第二个参数的字符串。以下是该实用程序的用法示例：  

```
 INPUT:      $util.str.toReplace("hello world", "hello", "mellow")
 OUTPUT:     "mellow world"
```

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

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

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

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

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

**`$extensions.evictFromApiCache(String, String, Object) : Object`**  
从 AWS AppSync 服务器端缓存中移出一个项目。第一个参数是类型名称。第二个参数是字段名称。第三个参数是一个对象，其中包含指定缓存键值的键值对项目。您必须按照与缓存解析器的 `cachingKey` 中的缓存键相同的顺序，将项目放入对象中。  
该实用程序仅适用于变更，而不适用于查询。

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

**`$extensions.setSubscriptionFilter(filterJsonObject)`**  
定义增强的订阅筛选条件。每个订阅通知事件都会根据提供的订阅筛选条件进行评估，如果所有筛选条件的评估结果均为 `true`，则向客户端发送通知。参数是 `filterJsonObject`，如下一节所述。  
您只能在订阅解析器的响应映射模板中使用该扩展方法。

**`$extensions.setSubscriptionInvalidationFilter(filterJsonObject)`**  
定义订阅失效筛选条件。根据失效负载评估订阅筛选条件，如果筛选条件的评估结果为 `true`，则使给定订阅失效。参数是 `filterJsonObject`，如下一节所述。  
您只能在订阅解析器的响应映射模板中使用该扩展方法。

**`$extensions.invalidateSubscriptions(invalidationJsonObject)`**  
用于启动变更导致的订阅失效。参数是 `invalidationJsonObject`，如下一节所述。  
只能在变更解析器的响应映射模板中使用该扩展。  
您最多只能在任何单个请求中使用 5 个唯一的 `$extensions.invalidateSubscriptions()` 方法调用。如果超过该限制，您将收到 GraphQL 错误。

## 论点： filterJsonObject
<a name="extensions-setSubscriptionInvalidationFilter"></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
}
```

### 字段：fieldName
<a name="extensions-fieldName"></a>

字符串类型 `fieldName` 指的是 GraphQL 架构中定义的一个字段，它与订阅通知负载中的 `fieldName` 匹配。在找到匹配项时，GraphQL 架构字段的 `value` 与订阅通知筛选条件的 `value` 进行比较。在以下示例中，`fieldName` 筛选条件与给定 GraphQL 类型中定义的 `service` 字段匹配。如果通知负载包含 `service` 字段，并且 `value` 等于 `AWS AppSync`，则筛选条件的评估结果为 `true`：

```
{
 "fieldName" : "service",
 "operator" : "eq",
 "value" : "AWS AppSync"
}
```

### 字段：value
<a name="extensions-value"></a>

根据运算符，该值可能具有不同的类型：
+ 单个数字或布尔值
  + 字符串示例：`"test"`、`"service"`
  + 数字示例：`1`、`2`、`45.75`
  + 布尔值示例：`true`、`false`
+ 数字或字符串对
  + 字符串对示例：`["test1","test2"]`、`["start","end"]`
  + 数字对示例：`[1,4]`、`[67,89]`、`[12.45, 95.45]`
+ 数字或字符串数组
  + 字符串数组示例：`["test1","test2","test3","test4","test5"]`
  + 数字数组示例：`[1,2,3,4,5]`、`[12.11,46.13,45.09,12.54,13.89]`

### 字段：operator
<a name="extensions-operator"></a>

一个区分大小写的字符串，可能具有以下值：


| 
| 
| 运算符 | 说明 | 可能的值类型 | 
| --- |--- |--- |
| eq | Equal | 整数、浮点数、字符串、布尔值 | 
| ne | Not equal | 整数、浮点数、字符串、布尔值 | 
| le | Less than or equal | 整数、浮点数、字符串 | 
| lt | Less than | 整数、浮点数、字符串 | 
| ge | Greater than or equal | 整数、浮点数、字符串 | 
| gt | Greater than | 整数、浮点数、字符串 | 
| contains | 检查集合中的子序列或值。 | 整数、浮点数、字符串 | 
| 不包含 | 检查集合中是否缺少子序列或缺少值。 | 整数、浮点数、字符串 | 
| 开始于 | 检查前缀。 | 字符串 | 
| in | 检查列表中是否有匹配的元素。 | 整数、浮点数或字符串数组 | 
| notIn | 检查列表中是否有不在列表中的匹配元素。 | 整数、浮点数或字符串数组 | 
| 介于 | 在两个值之间 | 整数、浮点数、字符串 | 
| 包含任何 | 包含常见元素 | 整数、浮点数、字符串 | 

下表介绍了如何在订阅通知中使用每个运算符。

------
#### [ eq (equal) ]

如果订阅通知字段值匹配并且严格等于筛选条件的值，则 `eq` 运算符的评估结果为 `true`。在以下示例中，如果订阅通知的 `service` 字段值等于 `AWS AppSync`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串、布尔值

```
{
 "fieldName" : "service",
 "operator" : "eq",
 "value" : "AWS AppSync"
}
```

------
#### [ ne (not equal) ]

如果订阅通知字段值与筛选条件的值不同，则 `ne` 运算符的评估结果为 `true`。在以下示例中，如果订阅通知的 `service` 字段值不同于 `AWS AppSync`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串、布尔值

```
{
 "fieldName" : "service",
 "operator" : "ne",
 "value" : "AWS AppSync"
}
```

------
#### [ le (less or equal) ]

如果订阅通知字段值小于或等于筛选条件的值，则 `le` 运算符的评估结果为 `true`。在以下示例中，如果订阅通知的 `size` 字段值小于或等于 `5`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串

```
{
 "fieldName" : "size",
 "operator" : "le",
 "value" : 5
}
```

------
#### [ lt (less than) ]

如果订阅通知字段值小于筛选条件的值，则 `lt` 运算符的评估结果为 `true`。在以下示例中，如果订阅通知的 `size` 字段值小于 `5`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串

```
{
 "fieldName" : "size",
 "operator" : "lt",
 "value" : 5
}
```

------
#### [ ge (greater or equal) ]

如果订阅通知字段值大于或等于筛选条件的值，则 `ge` 运算符的评估结果为 `true`。在以下示例中，如果订阅通知的 `size` 字段值大于或等于 `5`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串

```
{
 "fieldName" : "size",
 "operator" : "ge",
 "value" : 5
}
```

------
#### [ gt (greater than) ]

如果订阅通知字段值大于筛选条件的值，则 `gt` 运算符的评估结果为 `true`。在以下示例中，如果订阅通知的 `size` 字段值大于 `5`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串

```
{
 "fieldName" : "size",
 "operator" : "gt",
 "value" : 5
}
```

------
#### [ contains ]

`contains` 运算符检查集合或单个项目中的子字符串、子序列或值。如果订阅通知字段值包含筛选条件值，则具有 `contains` 运算符的筛选条件的评估结果为 `true`。在以下示例中，如果订阅通知的 `seats` 字段具有包含值 `10` 的数组值，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串

```
{
 "fieldName" : "seats",
 "operator" : "contains",
 "value" : 10
}
```

在另一个示例中，如果订阅通知的 `event` 字段将 `launch` 作为子字符串，则筛选条件的评估结果为 `true`。

```
{
 "fieldName" : "event",
 "operator" : "contains",
 "value" : "launch"
}
```

------
#### [ notContains ]

`notContains` 运算符检查在集合或单个项目中是否缺少子字符串、子序列或值。如果订阅通知字段值不包含筛选条件值，则具有 `notContains` 运算符的筛选条件的评估结果为 `true`。在以下示例中，如果订阅通知的 `seats` 字段具有不包含值 `10` 的数组值，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数、字符串

```
{
 "fieldName" : "seats",
 "operator" : "notContains",
 "value" : 10
}
```

在另一个示例中，如果订阅通知的 `event` 字段值没有将 `launch` 作为其子序列，则筛选条件的评估结果为 `true`。

```
{
 "fieldName" : "event",
 "operator" : "notContains",
 "value" : "launch"
}
```

------
#### [ beginsWith ]

`beginsWith` 运算符检查字符串中的前缀。如果订阅通知字段值以筛选条件的值开头，则包含 `beginsWith` 运算符的筛选条件的评估结果为 `true`。在以下示例中，如果订阅通知的 `service` 字段值以 `AWS` 开头，则筛选条件的评估结果为 `true`。

**可能的值类型：**字符串

```
{
 "fieldName" : "service",
 "operator" : "beginsWith",
 "value" : "AWS"
}
```

------
#### [ in ]

`in` 运算符在数组中检查匹配元素。如果订阅通知字段值在数组中存在，则包含 `in` 运算符的筛选条件的评估结果为 `true`。在以下示例中，如果订阅通知的 `severity` 字段具有数组 `[1,2,3]` 中存在的值之一，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数或字符串数组

```
{
 "fieldName" : "severity",
 "operator" : "in",
 "value" : [1,2,3]
}
```

------
#### [ notIn ]

`notIn` 运算符在数组中检查缺失元素。如果订阅通知字段值在数组中不存在，则包含 `notIn` 运算符的筛选条件的评估结果为 `true`。在以下示例中，如果订阅通知的 `severity` 字段具有数组 `[1,2,3]` 中不存在的值之一，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数或字符串数组

```
{
 "fieldName" : "severity",
 "operator" : "notIn",
 "value" : [1,2,3]
}
```

------
#### [ between ]

`between` 运算符检查两个数字或字符串之间的值。如果订阅通知字段值位于筛选条件的值对之间，则包含 `between` 运算符的筛选条件的评估结果为 `true`。在以下示例中，如果订阅通知的 `severity` 字段值为 `2`、`3`、`4`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数或字符串对

```
{
 "fieldName" : "severity",
 "operator" : "between",
 "value" : [1,5]
}
```

------
#### [ containsAny ]

`containsAny` 运算符检查数组中的相同元素。如果订阅通知字段设置值和筛选条件设置值的交集不为空，则具有 `containsAny` 运算符的筛选条件的评估结果为 `true`。在以下示例中，如果订阅通知的 `seats` 字段具有包含 `10` 或 `15` 的数组值，则筛选条件的评估结果为 `true`。这意味着如果订阅通知的 `seats` 字段值为 `[10,11]` 或 `[15,20,30]`，则筛选条件的评估结果为 `true`。

**可能的值类型：**整数、浮点数或字符串

```
{
 "fieldName" : "seats",
 "operator" : "containsAny",
 "value" : [10, 15]
}
```

------

### AND 逻辑
<a name="extensions-AND-logic"></a>

您可以在 `filterGroup` 数组的 `filters` 对象中定义多个条目，以使用 AND 逻辑组合多个筛选条件。在以下示例中，如果订阅通知的 `userId` 字段值等于 `1` 并且 `group` 字段的值为 `Admin` 或 `Developer`，则筛选条件的评估结果为 `true`。

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

### OR 逻辑
<a name="extensions-OR-logic"></a>

您可以在 `filterGroup` 数组中定义多个筛选条件对象，以使用 OR 逻辑组合多个筛选条件。在以下示例中，如果订阅通知的 `userId` 字段值等于 `1` 或者 `group` 字段的值为 `Admin` 或 `Developer`，则筛选条件的评估结果为 `true`。

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

### 异常
<a name="extensions-exceptions"></a>

请注意，使用筛选条件存在一些限制：
+ 在 `filters` 对象中，每个筛选条件最多可以具有 5 个唯一的 `fieldName` 项目。这意味着，您可以使用 AND 逻辑组合最多 5 个单独的 `fieldName` 对象。
+ `containsAny` 运算符最多可以具有 20 个值。
+ `in` 和 `notIn` 运算符最多可以具有 5 个值。
+ 每个字符串最多可以包含 256 个字符。
+ 每个字符串比较都区分大小写。
+ 嵌套对象筛选最多允许 5 个嵌套筛选级别。
+ 每个 `filterGroup` 最多可以具有 10 个 `filters`。这意味着，您可以使用 OR 逻辑最多组合 10 个 `filters`。
  + `in` 运算符是 OR 逻辑的特例。在以下示例中，具有两个 `filters`：

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

    前面的筛选条件组按以下方式进行评估，并计入最大筛选条件限制：

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

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

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

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

  ```
  $extensions.invalidateSubscriptions({
          "subscriptionField": "onUserDelete",
          "payload": {
                  "group": "Developer"
                  "type" : "Full-Time"
        }
      })
  ```

# AWS AppSync DynamoDB 的解析器映射模板参考
<a name="resolver-mapping-template-reference-dynamodb"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

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

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

`GetItem`请求映射文档允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB 发出`GetItem`请求，并允许您指定：
+ DynamoDB 中的项目的键
+ 是否使用一致性读取

`GetItem` 映射文档具有以下结构：

```
{
    "version" : "2017-02-28",
    "operation" : "GetItem",
    "key" : {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "consistentRead" : true,
    "projection" : {
        ...
    }
}
```

字段定义如下：

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

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

 **`version`**   
模板定义版本。目前支持 `2017-02-28` 和 `2018-05-29`。该值为必填项。

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

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

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

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

从 DynamoDB 返回的项目将自动转换为 GraphQL 和 JSON 基元类型，并且可以在映射上下文 (`$context.result`) 中使用。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)。

有关响应映射模板的更多信息，请参阅[解析器映射模板概述](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

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

以下示例是 GraphQL 查询 `getThing(foo: String!, bar: String!)` 的映射模板：

```
{
    "version" : "2017-02-28",
    "operation" : "GetItem",
    "key" : {
        "foo" : $util.dynamodb.toDynamoDBJson($ctx.args.foo),
        "bar" : $util.dynamodb.toDynamoDBJson($ctx.args.bar)
    },
    "consistentRead" : true
}
```

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

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

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

`PutItem` 映射文档具有以下结构：

```
{
    "version" : "2018-05-29",
    "operation" : "PutItem",
    "customPartitionKey" : "foo",
    "populateIndexFields" : boolean value,
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "attributeValues" : {
        "baz" : ... typed value
    },
    "condition" : {
       ...
    },
    "_version" : 1
}
```

字段定义如下：

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

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

 **`version`**   
模板定义版本。目前支持 `2017-02-28` 和 `2018-05-29`。该值为必填项。

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

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

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

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

 **`_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 类型转换的更多信息，请参阅[类型系统（响应映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)。

有关响应映射模板的更多信息，请参阅[解析器映射模板概述](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

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

以下示例是 GraphQL 变更 `updateThing(foo: String!, bar: String!, name: String!, version: Int!)` 的映射模板。

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

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "foo" : $util.dynamodb.toDynamoDBJson($ctx.args.foo),
        "bar" : $util.dynamodb.toDynamoDBJson($ctx.args.bar)
    },
    "attributeValues" : {
        "name"    : $util.dynamodb.toDynamoDBJson($ctx.args.name),
        "version" : $util.dynamodb.toDynamoDBJson($ctx.args.version)
    }
}
```

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

以下示例是 GraphQL 变更 `updateThing(foo: String!, bar: String!, name: String!, expectedVersion: Int!)` 的映射模板。

该示例检查以确保当前位于 DynamoDB 中的项目的 `version` 字段设置为 `expectedVersion`。

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "foo" : $util.dynamodb.toDynamoDBJson($ctx.args.foo),
        "bar" : $util.dynamodb.toDynamoDBJson($ctx.args.bar)
    },
    "attributeValues" : {
        "name"    : $util.dynamodb.toDynamoDBJson($ctx.args.name),
        #set( $newVersion = $context.arguments.expectedVersion + 1 )
        "version" : $util.dynamodb.toDynamoDBJson($newVersion)
    },
    "condition" : {
        "expression" : "version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : $util.dynamodb.toDynamoDBJson($expectedVersion)
        }
    }
}
```

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

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

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

`UpdateItem` 映射文档具有以下结构：

```
{
    "version" : "2018-05-29",
    "operation" : "UpdateItem",
    "customPartitionKey" : "foo",
    "populateIndexFields" : boolean value,
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "update" : {
        "expression" : "someExpression",
        "expressionNames" : {
           "#foo" : "foo"
       },
       "expressionValues" : {
           ":bar" : ... typed value
       }
    },
    "condition" : {
        ...
    },
    "_version" : 1
}
```

字段定义如下：

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

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

 **`version`**   
模板定义版本。目前支持 `2017-02-28` 和 `2018-05-29`。该值为必填项。

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

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

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

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

 **`_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 类型转换的更多信息，请参阅[类型系统（响应映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)。

有关响应映射模板的更多信息，请参阅[解析器映射模板概述](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

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

以下示例是 GraphQL 变更 `upvote(id: ID!)` 的映射模板。

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

```
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "update" : {
        "expression" : "ADD #votefield :plusOne, version :plusOne",
        "expressionNames" : {
            "#votefield" : "upvotes"
        },
        "expressionValues" : {
            ":plusOne" : { "N" : 1 }
        }
    }
}
```

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

以下示例是 GraphQL 变更 `updateItem(id: ID!, title: String, author: String, expectedVersion: Int!)` 的映射模板。

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

```
{
    "version" : "2017-02-28",

    "operation" : "UpdateItem",

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

    ## Set up some space to keep track of things we're updating **
    #set( $expNames  = {} )
    #set( $expValues = {} )
    #set( $expSet = {} )
    #set( $expAdd = {} )
    #set( $expRemove = [] )

    ## Increment "version" by 1 **
    $!{expAdd.put("version", ":newVersion")}
    $!{expValues.put(":newVersion", { "N" : 1 })}

    ## Iterate through each argument, skipping "id" and "expectedVersion" **
    #foreach( $entry in $context.arguments.entrySet() )
        #if( $entry.key != "id" && $entry.key != "expectedVersion" )
            #if( (!$entry.value) && ("$!{entry.value}" == "") )
                ## If the argument is set to "null", then remove that attribute from the item in DynamoDB **

                #set( $discard = ${expRemove.add("#${entry.key}")} )
                $!{expNames.put("#${entry.key}", "$entry.key")}
            #else
                ## Otherwise set (or update) the attribute on the item in DynamoDB **

                $!{expSet.put("#${entry.key}", ":${entry.key}")}
                $!{expNames.put("#${entry.key}", "$entry.key")}

                #if( $entry.key == "ups" || $entry.key == "downs" )
                    $!{expValues.put(":${entry.key}", { "N" : $entry.value })}
                #else
                    $!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })}
                #end
            #end
        #end
    #end

    ## Start building the update expression, starting with attributes we're going to SET **
    #set( $expression = "" )
    #if( !${expSet.isEmpty()} )
        #set( $expression = "SET" )
        #foreach( $entry in $expSet.entrySet() )
            #set( $expression = "${expression} ${entry.key} = ${entry.value}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Continue building the update expression, adding attributes we're going to ADD **
    #if( !${expAdd.isEmpty()} )
        #set( $expression = "${expression} ADD" )
        #foreach( $entry in $expAdd.entrySet() )
            #set( $expression = "${expression} ${entry.key} ${entry.value}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Continue building the update expression, adding attributes we're going to REMOVE **
    #if( !${expRemove.isEmpty()} )
        #set( $expression = "${expression} REMOVE" )

        #foreach( $entry in $expRemove )
            #set( $expression = "${expression} ${entry}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
    "update" : {
        "expression" : "${expression}"
        #if( !${expNames.isEmpty()} )
            ,"expressionNames" : $utils.toJson($expNames)
        #end
        #if( !${expValues.isEmpty()} )
            ,"expressionValues" : $utils.toJson($expValues)
        #end
    },

    "condition" : {
        "expression"       : "version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : $util.dynamodb.toDynamoDBJson($ctx.args.expectedVersion)
        }
    }
}
```

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

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

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

`DeleteItem` 映射文档具有以下结构：

```
{
    "version" : "2018-05-29",
    "operation" : "DeleteItem",
    "customPartitionKey" : "foo",
    "populateIndexFields" : boolean value,
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "condition" : {
        ...
    },
    "_version" : 1
}
```

字段定义如下：

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

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

** `version` **  
模板定义版本。目前支持 `2017-02-28` 和 `2018-05-29`。该值为必填项。

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

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

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

** `_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 类型转换的更多信息，请参阅[类型系统（响应映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)。

有关响应映射模板的更多信息，请参阅[解析器映射模板概述](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

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

以下示例是 GraphQL 变更 `deleteItem(id: ID!)` 的映射模板。如果具有此 ID 的项目存在，它将被删除。

```
{
    "version" : "2017-02-28",
    "operation" : "DeleteItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    }
}
```

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

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

```
{
    "version" : "2017-02-28",
    "operation" : "DeleteItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "condition" : {
        "expression"       : "attribute_not_exists(id) OR version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : $util.dynamodb.toDynamoDBJson($expectedVersion)
        }
    }
}
```

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

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

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

`Query` 映射文档具有以下结构：

```
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "query" : {
        "expression" : "some expression",
        "expressionNames" : {
            "#foo" : "foo"
        },
        "expressionValues" : {
            ":bar" : ... typed value
        }
    },
    "index" : "fooIndex",
    "nextToken" : "a pagination token",
    "limit" : 10,
    "scanIndexForward" : true,
    "consistentRead" : false,
    "select" : "ALL_ATTRIBUTES" | "ALL_PROJECTED_ATTRIBUTES" | "SPECIFIC_ATTRIBUTES",
    "filter" : {
        ...
    },
    "projection" : {
        ...
    }
}
```

字段定义如下：

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

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

** `version` **  
模板定义版本。目前支持 `2017-02-28` 和 `2018-05-29`。该值为必填项。

** `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` 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。该值为必填项。该字段是可选的，只应填充 `expression` 中使用的表达式属性值占位符的替换内容。

** `filter` **  
另一个筛选条件，该筛选条件可用于在从 DynamoDB 返回结果之前先筛选结果。有关筛选条件的更多信息，请参阅[筛选条件](aws-appsync-resolver-mapping-template-reference-dynamodb-filter.md)。该字段是可选的。

** `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/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)。该字段是可选的。

来自 DynamoDB 的结果将自动转换为 GraphQL 和 JSON 基元类型，并且可以在映射上下文 (`$context.result`) 中使用。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)。

有关响应映射模板的更多信息，请参阅[解析器映射模板概述](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

结果的结构如下所示：

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

字段定义如下：

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

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

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

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

以下示例是 GraphQL 查询 `getPosts(owner: ID!)` 的映射模板。

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

```
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "query" : {
        "expression" : "ownerId = :ownerId",
        "expressionValues" : {
            ":ownerId" : $util.dynamodb.toDynamoDBJson($context.arguments.owner)
        }
    },
    "index" : "owner-index"
}
```

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

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

`Scan`请求映射文档允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB 发出`Scan`请求，并允许您指定以下内容：
+ 排除结果的筛选条件
+ 要使用的索引
+ 要返回多少个项目
+ 是否使用一致性读取
+ 分页标记
+ 并行扫描

`Scan` 映射文档具有以下结构：

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "index" : "fooIndex",
    "limit" : 10,
    "consistentRead" : false,
    "nextToken" : "aPaginationToken",
    "totalSegments" : 10,
    "segment" : 1,
    "filter" : {
        ...
    },
    "projection" : {
        ...
    }
}
```

字段定义如下：

## Scan 字段
<a name="scan-list"></a>

### Scan 字段列表
<a name="scan-list-col"></a>

** `version` **  
模板定义版本。目前支持 `2017-02-28` 和 `2018-05-29`。该值为必填项。

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

** `filter` **  
一个筛选条件，可用于在返回来自 DynamoDB 的结果之前对其进行筛选。有关筛选条件的更多信息，请参阅[筛选条件](aws-appsync-resolver-mapping-template-reference-dynamodb-filter.md)。该字段是可选的。

** `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/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)。该字段是可选的。

DynamoDB 扫描返回的结果将自动转换为 GraphQL 和 JSON 基元类型，并且可以在映射上下文 (`$context.result`) 中使用。

有关 DynamoDB 类型转换的更多信息，请参阅[类型系统（响应映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)。

有关响应映射模板的更多信息，请参阅[解析器映射模板概述](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

结果的结构如下所示：

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

字段定义如下：

** `items` **  
包含 DynamoDB 扫描返回的项目的列表。

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

** `scannedCount` **  
在应用筛选条件表达式（如果有）之前 DynamoDB 检索的项目数。

## 示例 1
<a name="id11"></a>

以下示例是 GraphQL 查询 `allPosts` 的映射模板。

在本示例中，将返回表中的所有条目。

```
{
    "version" : "2017-02-28",
    "operation" : "Scan"
}
```

## 示例 2
<a name="id12"></a>

以下示例是 GraphQL 查询 `postsMatching(title: String!)` 的映射模板。

在本示例中，将返回表中标题以 `title` 参数开头的所有条目。

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "filter" : {
        "expression" : "begins_with(title, :title)",
        "expressionValues" : {
            ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title)
        },
    }
}
```

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

# 同步
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-sync"></a>

通过使用 `Sync` 请求映射文档，您可以从 DynamoDB 表中检索所有结果，然后仅接收自上次查询以来更改的数据（增量更新）。只能对版本控制的 DynamoDB 数据来源发出 `Sync` 请求。您可以指定以下内容：
+ 排除结果的筛选条件
+ 要返回多少个项目
+ 分页标记
+ 上次 `Sync` 操作开始时间

`Sync` 映射文档具有以下结构：

```
{
    "version" : "2018-05-29",
    "operation" : "Sync",
    "basePartitionKey": "Base Tables PartitionKey",
    "deltaIndexName": "delta-index-name",
    "limit" : 10,
    "nextToken" : "aPaginationToken",
    "lastSync" :  1550000000000,
    "filter" : {
        ...
    }
}
```

字段定义如下：

## Sync 字段
<a name="sync-list"></a>

### Sync 字段列表
<a name="sync-list-col"></a>

** `version` **  
模板定义版本。当前仅支持 `2018-05-29`。该值为必填项。

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

** `filter` **  
一个筛选条件，可用于在返回来自 DynamoDB 的结果之前对其进行筛选。有关筛选条件的更多信息，请参阅[筛选条件](aws-appsync-resolver-mapping-template-reference-dynamodb-filter.md)。该字段是可选的。

** `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 类型转换的更多信息，请参阅[类型系统（响应映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)。

有关响应映射模板的更多信息，请参阅[解析器映射模板概述](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

结果的结构如下所示：

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

字段定义如下：

** `items` **  
包含同步操作返回的项目的列表。

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

** `scannedCount` **  
在应用筛选条件表达式（如果有）之前 DynamoDB 检索的项目数。

** `startedAt` **  
同步操作开始的时刻，以纪元毫秒为单位，您可以在本地存储该值并在其他请求中将其用作 `lastSync` 参数。如果请求中包含分页令牌，则该值将与请求针对第一页结果返回的值相同。

## 示例
<a name="id14"></a>

以下示例是 GraphQL 查询 `syncPosts(nextToken: String, lastSync: AWSTimestamp)` 的映射模板。

在此示例中，如果省略 `lastSync`，则返回基表中的所有条目。如果提供了 `lastSync`，则只返回增量同步表中自 `lastSync` 以来发生更改的条目。

```
{
    "version" : "2018-05-29",
    "operation" : "Sync",
    "limit": 100,
    "nextToken": $util.toJson($util.defaultIfNull($ctx.args.nextToken, null)),
    "lastSync": $util.toJson($util.defaultIfNull($ctx.args.lastSync, null))
}
```

# BatchGetItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-batch-get-item"></a>

`BatchGetItem`请求映射文档允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB `BatchGetItem` 请求检索多个项目，可能跨多个表。对于此请求模板，您必须指定以下各项：
+ 要从中检索项目的表名称
+ 要从每个表中检索的项目的键

DynamoDB `BatchGetItem` 限制适用，并且无法提供**任何条件表达式**。

`BatchGetItem` 映射文档具有以下结构：

```
{
    "version" : "2018-05-29",
    "operation" : "BatchGetItem",
    "tables" : {
        "table1": {
           "keys": [
              ## Item to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              },
              ## Item2 to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              }
            ],
            "consistentRead": true|false,            
            "projection" : {
                 ...
            }
        },
        "table2": {
           "keys": [
              ## Item3 to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              },
              ## Item4 to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              }
            ],
            "consistentRead": true|false,
            "projection" : {
                 ...
            }
        }
    }
}
```

字段定义如下：

## BatchGetItem 字段
<a name="BatchGetItem-list"></a>

### BatchGetItem 字段列表
<a name="BatchGetItem-list-col"></a>

** `version` **  
模板定义版本。仅支持 `2018-05-29`。该值为必填项。

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

** `tables` **  
要从中检索项目的 DynamoDB 表。该值是一个映射，其中表名称被指定为映射的键。必须提供至少一个表。该 `tables` 值为必填项。    
** `keys` **  
DynamoDB 键列表，表示要检索的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。  
** `consistentRead` **  
执行*GetItem*操作时是否使用一致性读取。此值是可选的，默认为 *false*。  
**`projection`**  
用于指定从 DynamoDB 操作返回的属性的投影。有关投影的更多信息，请参阅[投影](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)。该字段是可选的。

要记住的事项：
+ 如果尚未从表中检索某个项目，则 *null* 元素将显示在该表的数据块中。
+ 根据在请求映射模板中提供调用结果的顺序，将按表对这些结果进行排序。
+ `BatchGetItem` 中的每个 `Get` 命令都是原子性的，但可以部分处理一个批次。如果由于错误而部分处理一个批处理，则未处理的键将作为 *unprocessedKeys* 块内的调用结果的一部分返回。
+  `BatchGetItem` 限制为 100 个键。

对于以下示例请求映射模板：

```
{
  "version": "2018-05-29",
  "operation": "BatchGetItem",
  "tables": {
    "authors": [
        {
          "author_id": {
            "S": "a1"
          }
        },
    ],
    "posts": [
        {
          "author_id": {
            "S": "a1"
          },
          "post_id": {
            "S": "p2"
          }
        }
    ],
  }
}
```

`$ctx.result` 中可用的调用结果如下所示：

```
{
   "data": {
     "authors": [null],
     "posts": [
        # Was retrieved
        {
          "author_id": "a1",
          "post_id": "p2",
          "post_title": "title",
          "post_description": "description",
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        # This item was not processed due to an error
        {
          "author_id": "a1"
        }
      ],
     "posts": []
   }
}
```

`$ctx.error` 包含有关该错误的详细信息。保证键**数据**、**unprocessedKeys** 和请求映射模板中提供的每个表键都出现在调用结果中。已删除的项目显示在**数据**块中。尚未处理的项目将在数据块中标记为 *null* 并置于 **unprocessedKeys** 块中。

要获得更完整的示例，请按照 DynamoDB 批处理教程进行操作，这里[有 AppSync 教程：Dynamo](tutorial-dynamodb-batch.md#aws-appsync-tutorial-dynamodb-batch) DB 批处理解析器。

# BatchDeleteItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-batch-delete-item"></a>

`BatchDeleteItem`请求映射文档允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB `BatchWriteItem` 请求删除多个项目，可能跨多个表。对于此请求模板，您必须指定以下各项：
+ 要从中删除项目的表名称
+ 要从每个表中删除的项目的键

DynamoDB `BatchWriteItem` 限制适用，并且无法提供**任何条件表达式**。

`BatchDeleteItem` 映射文档具有以下结构：

```
{
    "version" : "2018-05-29",
    "operation" : "BatchDeleteItem",
    "tables" : {
        "table1": [
        ## Item to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item2 to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
        "table2": [
        ## Item3 to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item4 to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
    }
}
```

字段定义如下：

## BatchDeleteItem 字段
<a name="BatchDeleteItem-list"></a>

### BatchDeleteItem 字段列表
<a name="BatchDeleteItem-list-col"></a>

** `version` **  
模板定义版本。仅支持 `2018-05-29`。该值为必填项。

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

** `tables` **  
要从中删除项目的 DynamoDB 表。每个表是 DynamoDB 键列表，表示要删除的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。必须提供至少一个表。`tables` 值是必需的。

要记住的事项：
+ 与 `DeleteItem` 操作相反，响应中不会返回完全删除的项目。只返回传递的键。
+ 如果尚未从表中删除某个项目，*null* 元素将显示在该表的数据块中。
+ 根据在请求映射模板中提供调用结果的顺序，将按表对这些结果进行排序。
+ `BatchDeleteItem` 中的每个 `Delete` 命令都是原子性的。但是，可以部分处理一个批处理。如果由于错误而部分处理一个批处理，则未处理的键将作为 *unprocessedKeys* 块内的调用结果的一部分返回。
+  `BatchDeleteItem` 限制为 25 个键。
+ **不**支持与冲突检测功能一起使用此操作。两者同时使用可能会导致错误。

对于以下示例请求映射模板：

```
{
  "version": "2018-05-29",
  "operation": "BatchDeleteItem",
  "tables": {
    "authors": [
        {
          "author_id": {
            "S": "a1"
          }
        },
    ],
    "posts": [
        {
          "author_id": {
            "S": "a1"
          },
          "post_id": {
            "S": "p2"
          }
        }
    ],
  }
}
```

`$ctx.result` 中可用的调用结果如下所示：

```
{
   "data": {
     "authors": [null],
     "posts": [
        # Was deleted
        {
          "author_id": "a1",
          "post_id": "p2"
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        # This key was not processed due to an error
        {
          "author_id": "a1"
        }
      ],
     "posts": []
   }
}
```

`$ctx.error` 包含有关该错误的详细信息。保证键**数据**、**unprocessedKeys** 和请求映射模板中提供的每个表键都出现在调用结果中。已删除的项目存在于**数据**块中。尚未处理的项目将在数据块中标记为 *null* 并置于 **unprocessedKeys** 块中。

要获得更完整的示例，请按照 DynamoDB 批处理教程进行操作，这里[有 AppSync 教程：Dynamo](tutorial-dynamodb-batch.md#aws-appsync-tutorial-dynamodb-batch) DB 批处理解析器。

# BatchPutItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-batch-put-item"></a>

`BatchPutItem`请求映射文档允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB 发出`BatchWriteItem`请求，要求将多个项目放置在多个表中。对于此请求模板，您必须指定以下各项：
+ 要将项目放置在其中的表名称
+ 要放置在每个表中的完整项目

DynamoDB `BatchWriteItem` 限制适用，并且无法提供**任何条件表达式**。

`BatchPutItem` 映射文档具有以下结构：

```
{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "table1": [
        ## Item to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item2 to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
        "table2": [
        ## Item3 to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item4 to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
    }
}
```

字段定义如下：

## BatchPutItem 字段
<a name="BatchPutItem-list"></a>

### BatchPutItem 字段列表
<a name="BatchPutItem-list-col"></a>

** `version` **  
模板定义版本。仅支持 `2018-05-29`。该值为必填项。

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

** `tables` **  
要在其中放置项目的 DynamoDB 表。每个表条目表示要为该特定表插入的 DynamoDB 项目列表。必须提供至少一个表。该值为必填项。

要记住的事项：
+ 如果成功，响应中将返回完全插入的项目。
+ 如果尚未向表中插入项目，*null* 元素将显示在该表的数据块中。
+ 根据在请求映射模板中提供插入的项目的顺序，按表对这些项目进行排序。
+ `BatchPutItem` 中的每个 `Put` 命令都是原子性的，但可以部分处理一个批次。如果由于错误而部分处理一个批处理，则未处理的键将作为 *unprocessedKeys* 块内的调用结果的一部分返回。
+  `BatchPutItem` 限制为 25 个项目。
+ **不**支持与冲突检测功能一起使用此操作。两者同时使用可能会导致错误。

对于以下示例请求映射模板：

```
{
  "version": "2018-05-29",
  "operation": "BatchPutItem",
  "tables": {
    "authors": [
        {
          "author_id": {
            "S": "a1"
          },
          "author_name": {
            "S": "a1_name"
          }
        },
    ],
    "posts": [
        {
          "author_id": {
            "S": "a1"
          },
          "post_id": {
            "S": "p2"
          },
          "post_title": {
            "S": "title"
          }
        }
    ],
  }
}
```

`$ctx.result` 中可用的调用结果如下所示：

```
{
   "data": {
     "authors": [
         null
     ],
     "posts": [
        # Was inserted
        {
          "author_id": "a1",
          "post_id": "p2",
          "post_title": "title"
        }
     ]
   },
   "unprocessedItems": {
     "authors": [
        # This item was not processed due to an error
        {
          "author_id": "a1",
          "author_name": "a1_name"
        }
      ],
     "posts": []
   }
}
```

`$ctx.error` 包含有关该错误的详细信息。保证键**数据**、**unprocessedItems** 和请求映射模板中提供的每个表键都出现在调用结果中。已插入的项目存在于**数据**块中。尚未处理的项目将在数据块中标记为 *null* 并置于 **unprocessedItems** 块中。

要获得更完整的示例，请按照 DynamoDB 批处理教程进行操作，这里[有 AppSync 教程：Dynamo](tutorial-dynamodb-batch.md#aws-appsync-tutorial-dynamodb-batch) DB 批处理解析器。

# TransactGetItems
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-transact-get-items"></a>

`TransactGetItems`请求映射文档允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB 发出`TransactGetItems`请求，以检索多个项目，可能跨多个表。对于此请求模板，您必须指定以下各项：
+ 从中检索项目的每个请求项目的表名称
+ 要从每个表中检索的每个请求项的键

DynamoDB `TransactGetItems` 限制适用，并且无法提供**任何条件表达式**。

`TransactGetItems` 映射文档具有以下结构：

```
{
    "version": "2018-05-29",
    "operation": "TransactGetItems",
    "transactItems": [
       ## First request item
       {
           "table": "table1",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "projection" : {
                ...
           }
       },
       ## Second request item
       {
           "table": "table2",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "projection" : {
                ...
           }
       }
    ]
}
```

字段定义如下：

## TransactGetItems 字段
<a name="TransactGetItems-list"></a>

### TransactGetItems 字段列表
<a name="TransactGetItems-list-col"></a>

** `version` **  
模板定义版本。仅支持 `2018-05-29`。该值为必填项。

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

** `transactItems` **  
要包含的请求项目。该值是请求项目的数组。必须提供至少一个请求项目。该 `transactItems` 值为必填项。    
** `table` **  
要从中检索项目的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `key` **  
DynamoDB 键，表示要检索的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。  
**`projection`**  
用于指定从 DynamoDB 操作返回的属性的投影。有关投影的更多信息，请参阅[投影](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)。该字段是可选的。

要记住的事项：
+ 如果事务成功，`items` 块中检索项目的顺序将与请求项目的顺序相同。
+ 交易是以 all-or-nothing某种方式进行的。如果任何请求项目导致错误，则整个交易都不会执行，并返回错误详细信息。
+ 无法检索的请求项目不是错误。相反，*null* 元素会出现在相应位置的 *items* 块中。
+ 如果交易的错误是 *TransactionCanceledException*，则`cancellationReasons`区块将被填充。`cancellationReasons` 块中取消原因的顺序将与请求项目的顺序相同。
+  `TransactGetItems` 限制为 100 个请求项目。

对于以下示例请求映射模板：

```
{
    "version": "2018-05-29",
    "operation": "TransactGetItems",
    "transactItems": [
       ## First request item
       {
           "table": "posts",
           "key": {
               "post_id": {
                 "S": "p1"
               }
           }
       },
       ## Second request item
       {
           "table": "authors",
           "key": {
               "author_id": {
                 "S": a1
               }
           }
       }
    ]
}
```

如果事务成功并且只检索第一个请求的项目，则 `$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` 中。

要查看更完整的示例，请按照 DynamoDB 事务教程进行操作，这里 AppSync 有教[程：Dynamo](tutorial-dynamodb-transact.md#aws-appsync-tutorial-dynamodb-transact) DB 事务解析器。

# TransactWriteItems
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-transact-write-items"></a>

`TransactWriteItems`请求映射文档允许您告诉 D AWS AppSync ynamoDB 解析器向 DynamoDB `TransactWriteItems` 请求写入多个项目，可能写入多个表。对于此请求模板，您必须指定以下各项：
+ 每个请求项目的目标表名称
+ 要执行的每个请求项目的操作。支持四种类型的操作：*PutItem*、*UpdateItem*DeleteItem**、和 *ConditionCheck* 
+ 要写入的每个请求项目的键

DynamoDB `TransactWriteItems` 限制适用。

`TransactWriteItems` 映射文档具有以下结构：

```
{
    "version": "2018-05-29",
    "operation": "TransactWriteItems",
    "transactItems": [
       {
           "table": "table1",
           "operation": "PutItem",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "attributeValues": {
               "baz": ... typed value
           },
           "condition": {
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       },
       {
           "table":"table2",
           "operation": "UpdateItem",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "update": {
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               }
           },
           "condition": {
               "expression": "someExpression",
               "expressionNames": {
                   "#foo":"foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       },
       {
           "table": "table3",
           "operation": "DeleteItem",
           "key":{
               "foo": ... typed value,
               "bar": ... typed value
           },
           "condition":{
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       },
       {
           "table": "table4",
           "operation": "ConditionCheck",
           "key":{
               "foo": ... typed value,
               "bar": ... typed value
           },
           "condition":{
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       }
    ]
}
```

## TransactWriteItems 字段
<a name="TransactWriteItems-list"></a>

### TransactWriteItems 字段列表
<a name="TransactWriteItems-list-col"></a>

**字段定义如下：**    
** `version` **  
模板定义版本。仅支持 `2018-05-29`。该值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `TransactWriteItems` DynamoDB 操作，该字段必须设置为 `TransactWriteItems`。该值为必填项。  
** `transactItems` **  
要包含的请求项目。该值是请求项目的数组。必须提供至少一个请求项目。该 `transactItems` 值为必填项。  
对于 `PutItem`，字段定义如下：    
** `table` **  
目标 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `PutItem` DynamoDB 操作，该字段必须设置为 `PutItem`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要放置的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。该值为必填项。  
** `attributeValues` **  
要放入 DynamoDB 中的项目的其余属性。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。该字段是可选的。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `PutItem` 请求将覆盖该项目的任何现有条目。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)。该值为可选项。
对于 `UpdateItem`，字段定义如下：    
** `table` **  
要更新的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `UpdateItem` DynamoDB 操作，该字段必须设置为 `UpdateItem`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要更新的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。该值为必填项。  
** `update` **  
`update` 部分用于指定一个更新表达式，以描述如何更新 DynamoDB 中的项目。有关如何编写更新表达式的更多信息，请参阅 [DynamoDB 文档 UpdateExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)。此部分是必需的。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `UpdateItem` 请求将更新现有条目，而不考虑其当前状态。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)。该值为可选项。
对于 `DeleteItem`，字段定义如下：    
** `table` **  
要在其中删除项目的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `DeleteItem` DynamoDB 操作，该字段必须设置为 `DeleteItem`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要删除的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。该值为必填项。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。如果未指定条件，则 `DeleteItem` 请求将删除项目，而不考虑其当前状态。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)。该值为可选项。
对于 `ConditionCheck`，字段定义如下：    
** `table` **  
要在其中检查条件的 DynamoDB 表。该值是表名的字符串。该 `table` 值为必填项。  
** `operation` **  
要执行的 DynamoDB 操作。要执行 `ConditionCheck` DynamoDB 操作，该字段必须设置为 `ConditionCheck`。该值为必填项。  
** `key` **  
DynamoDB 键，表示要检查条件的项目的主键。DynamoDB 项目可能具有单个哈希键，也可能具有哈希键和排序键，具体取决于表结构。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。该值为必填项。  
** `condition` **  
根据 DynamoDB 中已有的对象状态，确定请求是否应成功的条件。您可以指定在状况检查失败时是否重新检索现有项目。有关事务条件的更多信息，请参阅[事务条件表达式](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)。该值为必填项。

要记住的事项：
+ 如果成功，响应中只返回请求项目的键。键的顺序将与请求项目的顺序相同。
+ 交易是以 all-or-nothing某种方式进行的。如果任何请求项目导致错误，则整个交易都不会执行，并返回错误详细信息。
+ 不能有两个请求项目针对同一个项目。否则它们会导致*TransactionCanceledException*错误。
+ 如果交易的错误是 *TransactionCanceledException*，则`cancellationReasons`区块将被填充。如果请求项目的条件检查失败**且** 您没有将 `returnValuesOnConditionCheckFailure` 指定为 `false`，则表中存在的项目将被检索并存储在 `cancellationReasons` 块的相应位置的 `item` 中。
+  `TransactWriteItems` 限制为 100 个请求项目。
+ **不**支持与冲突检测功能一起使用此操作。两者同时使用可能会导致错误。

对于以下示例请求映射模板：

```
{
    "version": "2018-05-29",
    "operation": "TransactWriteItems",
    "transactItems": [
       {
           "table": "posts",
           "operation": "PutItem",
           "key": {
               "post_id": {
                   "S": "p1"
               }
           },
           "attributeValues": {
               "post_title": {
                   "S": "New title"
               },
               "post_description": {
                   "S": "New description"
               }
           },
           "condition": {
               "expression": "post_title = :post_title",
               "expressionValues": {
                   ":post_title": {
                       "S": "Expected old title"
                   }
               }
           }
       },
       {
           "table":"authors",
           "operation": "UpdateItem",
           "key": {
               "author_id": {
                   "S": "a1"
               },
           },
           "update": {
               "expression": "SET author_name = :author_name",
               "expressionValues": {
                   ":author_name": {
                       "S": "New name"
                   }
               }
           },
       }
    ]
}
```

如果事务成功，`$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` 中。

要查看更完整的示例，请按照 DynamoDB 事务教程进行操作，这里 AppSync 有教[程：Dynamo](tutorial-dynamodb-transact.md#aws-appsync-tutorial-dynamodb-transact) DB 事务解析器。

# 类型系统（请求映射）
<a name="aws-appsync-resolver-mapping-template-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="aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses"></a>

收到来自 DynamoDB 的响应时 AWS AppSync ，会自动将其转换为 GraphQL 和 JSON 原始类型。将解码 DynamoDB 中的每个属性，并在响应映射上下文中返回。

例如，如果 DynamoDB 返回以下内容：

```
{
    "id" : { "S" : "1234" },
    "name" : { "S" : "Nadia" },
    "age" : { "N" : 25 }
}
```

然后， AWS AppSync DynamoDB 解析器将其转换为 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="aws-appsync-resolver-mapping-template-reference-dynamodb-filter"></a>

在使用 `Query` 和 `Scan` 操作查询 DynamoDB 中的对象时，您可以选择指定 `filter` 以评估结果并仅返回所需的值。

`Query` 或 `Scan` 映射文档的筛选映射部分具有以下结构：

```
"filter" : {
    "expression" : "filter expression"
    "expressionNames" : {
        "#name" : "name",
    },
    "expressionValues" : {
        ":value" : ... typed value
    },
}
```

字段定义如下：

** `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` 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。必须指定此值。该字段是可选的，只应填充 `expression` 中使用的表达式属性值占位符的替换内容。

## 示例
<a name="id18"></a>

以下示例是映射模板的筛选条件部分，其中，只有在标题以 `title` 参数开头时，才会返回从 DynamoDB 中检索的条目。

```
"filter" : {
    "expression" : "begins_with(#title, :title)",
    "expressionNames" : {
        "#title" : "title"
    },
    "expressionValues" : {
        ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title)
    }
}
```

# 条件表达式
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions"></a>

在您使用 `PutItem`、`UpdateItem` 和 `DeleteItem` DynamoDB 操作变更 DynamoDB 中的对象时，您可以选择指定一个条件表达式，以根据执行操作之前 DynamoDB 中的已有对象状态控制请求是否应成功。

D AWS AppSync ynamoDB 解析器允许`PutItem`在`UpdateItem`、`DeleteItem`和请求映射文档中指定条件表达式，还允许在条件失败且对象未更新时遵循的策略。

## 示例 1
<a name="id19"></a>

以下 `PutItem` 映射文档没有条件表达式。因此，即使已存在具有相同键的项目，它也会将项目放置在 DynamoDB 中，从而覆盖现有的项目。

```
{
   "version" : "2017-02-28",
   "operation" : "PutItem",
   "key" : {
      "id" : { "S" : "1" }
   }
}
```

## 示例 2
<a name="id20"></a>

以下 `PutItem` 映射文档确实具有一个条件表达式，只有在 DynamoDB 中*不* 存在具有相同键的项目时，该操作才会成功。

```
{
   "version" : "2017-02-28",
   "operation" : "PutItem",
   "key" : {
      "id" : { "S" : "1" }
   },
   "condition" : {
      "expression" : "attribute_not_exists(id)"
   }
}
```

默认情况下，如果条件检查失败， AWS AppSync DynamoDB 解析器会返回变异错误。但是， AWS AppSync DynamoDB 解析器提供了一些其他功能来帮助开发人员处理一些常见的边缘情况：
+ 如果 D AWS AppSync ynamoDB 解析器可以确定 DynamoDB 中的当前值与所需结果相匹配，则它会将该操作视为成功了。
+ 您可以将解析器配置为调用自定义 Lambda 函数来决定 Dynam AWS AppSync oDB 解析器应如何处理故障，而不是返回错误。

在[处理条件检查失败](#aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling)一节中更详细地介绍了这些内容。

[有关 DynamoDB 条件表达式的更多信息，请参阅 DynamoDB 文档。 ConditionExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)

## 指定条件
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-specification"></a>

`PutItem`、`UpdateItem` 和 `DeleteItem` 请求映射文档都允许指定可选的 `condition` 部分。如果省略，则不会进行条件检查。如果指定，条件必须为 true，操作才能成功。

`condition` 部分具有以下结构：

```
"condition" : {
    "expression" : "someExpression"
    "expressionNames" : {
        "#foo" : "foo"
    },
    "expressionValues" : {
        ":bar" : ... typed value
    },
    "equalsIgnore" : [ "version" ],
    "consistentRead" : true,
    "conditionalCheckFailedHandler" : {
        "strategy" : "Custom",
        "lambdaArn" : "arn:..."
    }
}
```

下列字段指定条件：

** `expression` **  
更新表达式本身。有关如何编写条件表达式的更多信息，请参阅 [DynamoDB 文档 ConditionExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)。必须指定该字段。

** `expressionNames` **  
以键值对形式替换表达式属性名称占位符。键对应于 *expression* 中使用的名称占位符，值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 *expression* 中使用的表达式属性名称占位符的替换内容。

** `expressionValues` **  
以键值对形式替换表达式属性值占位符。键对应于 expression 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅[类型系统（请求映射）](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)。必须指定此值。该字段是可选的，只应填充 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` 时，必须指定该字段。有关如何使用该功能的更多信息，请参阅[处理条件检查失败](#aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling)。

## 处理条件检查失败
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling"></a>

默认情况下，当条件检查失败时，D AWS AppSync ynamoDB 解析器会返回变异错误，并返回 DynamoDB 中对象的当前值。但是， AWS AppSync DynamoDB 解析器提供了一些其他功能来帮助开发人员处理一些常见的边缘情况：
+ 如果 D AWS AppSync ynamoDB 解析器可以确定 DynamoDB 中的当前值与所需结果相匹配，则它会将该操作视为成功了。
+ 您可以将解析器配置为调用自定义 Lambda 函数来决定 Dynam AWS AppSync oDB 解析器应如何处理故障，而不是返回错误。

此过程的流程图为：

![\[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="checking-for-the-desired-result"></a>

当条件检查失败时，D AWS AppSync ynamoDB 解析器会执行 DynamoDB 请求`GetItem`，以从 DynamoDB 获取项目的当前值。默认情况下，它将使用强一致性读取，但这可以使用 `condition` 数据块中的 `consistentRead` 字段进行配置，并将当前值与预期结果进行比较：
+ 对于该`PutItem`操作，D AWS AppSync ynamoDB 解析器会将当前值与其尝试写入的值进行比较，不包括比较中列出的`equalsIgnore`任何属性。如果项目相同，则将操作视为成功并返回从 DynamoDB 中检索的项目。否则，它将遵循所配置的策略。

  例如，如果 `PutItem` 请求映射文档如下所示：

  ```
  {
     "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" ]
     }
  }
  ```

  当前位于 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="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 }
}
```

并且响应映射模板如下所示：

```
{
   "id" : $util.toJson($context.result.id),
   "Name" : $util.toJson($context.result.name),
   "theVersion" : $util.toJson($context.result.version)
}
```

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="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](aws-appsync-resolver-mapping-template-reference-dynamodb-putitem.md)。

  ```
  {
      "attributeValues": { ... },
      "condition": {
          "equalsIgnore" = [ ... ],
          "consistentRead" = true
      }
  }
  ```

  对于 `UpdateItem`，`retryMapping` 部分具有以下结构。有关该`update`部分的说明，请参见[UpdateItem](aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem.md)。

  ```
  {
      "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="aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions"></a>

事务条件表达式可用于 `TransactWriteItems` 中所有四种类型的操作的请求映射模板，即 `PutItem`、`DeleteItem`、`UpdateItem` 和 `ConditionCheck`。

对于 `PutItem`、`DeleteItem` 和 `UpdateItem`，事务条件表达式是可选的。对于 `ConditionCheck`，事务条件表达式是必需的。

## 示例 1
<a name="id22"></a>

以下事务 `DeleteItem` 映射文档没有条件表达式。因此，它删除 DynamoDB 中的项目。

```
{
   "version": "2018-05-29",
   "operation": "TransactWriteItems",
   "transactItems": [
      {
         "table": "posts",
         "operation": "DeleteItem",
         "key": {
            "id": { "S" : "1" }
         }
      }
   ]
}
```

## 示例 2
<a name="id23"></a>

以下事务 `DeleteItem` 映射文档确实具有一个事务条件表达式，只有在该文章的作者等于特定姓名时，操作才会成功。

```
{
   "version": "2018-05-29",
   "operation": "TransactWriteItems",
   "transactItems": [
      {
         "table": "posts",
         "operation": "DeleteItem",
         "key": {
            "id": { "S" : "1" }
         }
         "condition": {
            "expression": "author = :author",
            "expressionValues": {
               ":author": { "S" : "Chunyan" }
            }
         }
      }
   ]
}
```

如果条件检查失败，则会导致 `TransactionCanceledException`，错误详细信息将在 `$ctx.result.cancellationReasons` 中返回。请注意，默认情况下，DynamoDB 中导致条件检查失败的旧项目将在 `$ctx.result.cancellationReasons` 中返回。

## 指定条件
<a name="id24"></a>

`PutItem`、`UpdateItem` 和 `DeleteItem` 请求映射文档都允许指定可选的 `condition` 部分。如果省略，则不会进行条件检查。如果指定，条件必须为 true，操作才能成功。`ConditionCheck` 必须具有要指定的 `condition` 部分。条件必须为 true，整个事务才能成功。

`condition` 部分具有以下结构：

```
"condition": {
    "expression": "someExpression",
    "expressionNames": {
        "#foo": "foo"
    },
    "expressionValues": {
        ":bar": ... typed value
    },
    "returnValuesOnConditionCheckFailure": false
}
```

下列字段指定条件：

** `expression` **  
更新表达式本身。有关如何编写条件表达式的更多信息，请参阅 [DynamoDB 文档 ConditionExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)。必须指定该字段。

** `expressionNames` **  
以键值对形式替换表达式属性名称占位符。键对应于 *expression* 中使用的名称占位符，值必须是与 DynamoDB 中的项目的属性名称对应的字符串。该字段是可选的，只应填充 *expression* 中使用的表达式属性名称占位符的替换内容。

** `expressionValues` **  
以键值对形式替换表达式属性值占位符。键对应于 expression 中使用的值占位符，而值必须为类型化值。有关如何指定“类型化值”的更多信息，请参阅“类型系统（请求映射）”。必须指定此值。该字段是可选的，只应填充 expression 中使用的表达式属性值占位符的替换内容。

** `returnValuesOnConditionCheckFailure` **  
指定在条件检查失败时是否重新检索 DynamoDB 中的项目。检索到的项目将位于 `$ctx.result.cancellationReasons[$index].item` 中，其中 `$index` 是未通过条件检查的请求项目的索引。该值默认为 true。

# 投影
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-projections"></a>

在使用 `GetItem`、`Scan`、`Query`、`BatchGetItem` 和 `TransactGetItems` 操作读取 DynamoDB 中的对象时，您可以选择指定一个投影以指定所需的属性。投影具有以下结构，与筛选条件类似：

```
"projection" : {
    "expression" : "projection expression"
    "expressionNames" : {
        "#name" : "name",
    }
}
```

字段定义如下：

**`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="id25"></a>

以下示例是 VTL 映射模板的投影部分，其中仅从 DynamoDB 返回 `author` 和 `id` 属性：

```
"projection" : {
    "expression" : "#author, id",
    "expressionNames" : {
        "#author" : "author"
    }
}
```

**提示**  
[你可以使用 \$1context.info 访问你的 GraphQL 请求选择集。 selectionSetList](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html#aws-appsync-resolver-context-reference-info)。可以通过该字段根据您的要求动态构建投影表达式。

**注意**  
在将投影表达式与 `Query` 和 `Scan` 运算一起使用时，`select` 的值必须为 `SPECIFIC_ATTRIBUTES`。有关更多信息，请参阅 [DynamoDB 文档](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-Select)。

# AWS AppSync RDS 的解析器映射模板参考
<a name="resolver-mapping-template-reference-rds"></a>

 AWS AppSync RDS 解析器映射模板允许开发人员向适用于 Amazon Aurora Serverless 的数据 API 发送 SQL 查询并获取这些查询的结果。

## 请求映射模板
<a name="request-mapping-template"></a>

RDS 请求映射模板相当简单：

```
{
    "version": "2018-05-29",
    "statements": [],
    "variableMap": {},
    "variableTypeHintMap": {}
}
```

下面是 RDS 请求映射模板的 JSON 架构表示形式（解析后）：

```
{
    "definitions": {},
    "$schema": "https://json-schema.org/draft-07/schema#",
    "$id": "https://example.com/root.json",
    "type": "object",
    "title": "The Root Schema",
    "required": [
        "version",
        "statements",
        "variableMap"
    ],
    "properties": {
        "version": {
            "$id": "#/properties/version",
            "type": "string",
            "title": "The Version Schema",
            "default": "",
            "examples": [
                "2018-05-29"
            ],
            "enum": [
                "2018-05-29"
            ],
            "pattern": "^(.*)$"
        },
        "statements": {
            "$id": "#/properties/statements",
            "type": "array",
            "title": "The Statements Schema",
            "items": {
                "$id": "#/properties/statements/items",
                "type": "string",
                "title": "The Items Schema",
                "default": "",
                "examples": [
                    "SELECT * from BOOKS"
                ],
                "pattern": "^(.*)$"
            }
        },
        "variableMap": {
            "$id": "#/properties/variableMap",
            "type": "object",
            "title": "The Variablemap Schema"
        },
        "variableTypeHintMap": {
            "$id": "#/properties/variableTypeHintMap",
            "type": "object",
            "title": "The variableTypeHintMap Schema"
        }
    }
}
```

以下是一个具有静态查询的请求映射模板示例：

```
{
    "version": "2018-05-29",
    "statements": [
        "select title, isbn13 from BOOKS where author = 'Mark Twain'"
    ]
}
```

## 版本
<a name="version"></a>

version 字段是所有请求映射模板通用的，用于定义模板使用的版本。version 字段为必填项。“2018-05-29”值是 Amazon RDS 映射模板支持的唯一版本。

```
"version": "2018-05-29"
```

## 声明和 VariableMap
<a name="statements-variablemap"></a>

statements 数组是开发人员提供的查询的占位符。目前，每个请求映射模板最多支持两个查询。`variableMap` 是一个可选字段，它包含可用于使 SQL 语句更短且更易读的别名。例如，可以编写以下代码：

```
{
"version": "2018-05-29",
    "statements": [
        "insert into BOOKS VALUES (:AUTHOR, :TITLE, :ISBN13)",
        "select * from BOOKS WHERE isbn13 = :ISBN13"
    ],
    "variableMap": {
        ":AUTHOR": $util.toJson($ctx.args.newBook.author),
        ":TITLE": $util.toJson($ctx.args.newBook.title),
        ":ISBN13": $util.toJson($ctx.args.newBook.isbn13)
    }
}
```

AWS AppSync 将使用变量映射值来构造将发送到 Amazon Aurora 无服务器数据 API 的**[SqlParameterized](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html)**查询。SQL 语句是使用变量映射中提供的参数执行的，从而消除了 SQL 注入风险。

## VariableTypeHintMap
<a name="variabletypehintmap"></a>

`variableTypeHintMap` 是一个可选字段，它包含可用于发送 [SQL 参数](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html)类型提示的别名类型。这些类型提示避免了 SQL 语句中的显式转换，从而使这些语句变得更短。例如，可以编写以下代码：

```
{
    "version": "2018-05-29",
    "statements": [
        "insert into LOGINDATA VALUES (:ID, :TIME)",
        "select * from LOGINDATA WHERE id = :ID"
     ],
     "variableMap": {
        ":ID": $util.toJson($ctx.args.id),
        ":TIME": $util.toJson($ctx.args.time)
     },
     "variableTypeHintMap": {
        ":id": "UUID",
        ":time": "TIME"
     }
}
```

AWS AppSync 将使用变量映射值来构造发送到 Amazon Aurora 无服务器数据 API 的查询。它还使用 `variableTypeHintMap` 数据，并将类型的信息发送到 RDS。可以在[此处](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html)找到 RDS 支持的 `typeHints`。

# AWS AppSync 的解析器映射模板参考 OpenSearch
<a name="resolver-mapping-template-reference-elasticsearch"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

亚马逊 OpenSearch 服务的 AWS AppSync 解析器使您能够使用 GraphQL 存储和检索账户中 OpenSearch 现有服务域中的数据。此解析器的工作原理是允许您将传入的 GraphQL 请求映射到服务请求，然后将 OpenSearch 服务响应映射 OpenSearch 回 GraphQL。本节介绍支持的 OpenSearch 服务操作的映射模板。

## 请求映射模板
<a name="request-mapping-template"></a>

大多数 OpenSearch 服务请求映射模板都有一个共同的结构，其中只有几个部分会发生变化。以下示例针对 OpenSearch 服务域运行搜索，其中文档组织在名为的索引下`post`。搜索参数在 `body` 部分定义，而许多常用查询子句在 `query` 字段中定义。此示例将搜索在文档的 `"Nadia"` 字段中包含 `"Bailey"` 和/或 `author` 的文档。

```
{
    "version":"2017-02-28",
    "operation":"GET",
    "path":"/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 中使用了两个常见的响应映射模板：

 **结果列表** 

```
[
    #foreach($entry in $context.result.hits.hits)
      #if( $velocityCount > 1 ) , #end
        $utils.toJson($entry.get("_source"))
    #end
]
```

 **单个项目** 

```
$utils.toJson($context.result.get("_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>/_doc/<_id>"
"path" : "/<indexname>/_doc"
"path" : "/<indexname>/_search"
"path" : "/<indexname>/_update/<_id>
```

评估映射模板时，此路径将作为 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”匹配的所有文档：

```
"body":{
    "from":0,
    "size":50,
    "query" : {
        "match" : {
            "city" : "seattle"
        }
    }
}
```

 **示例 2** 

返回将“washington”作为城市或州匹配的所有文档。

```
"body":{
    "from":0,
    "size":50,
    "query" : {
        "multi_match" : {
            "query" : "washington",
            "fields" : ["city", "state"]
        }
    }
}
```

## 传递变量
<a name="passing-variables"></a>

**注意**  
这仅适用于请求映射模板。

还可以在 VTL 语句中作为评估的一部分传递变量。例如，假设您具有以下 GraphQL 查询，如下所示：

```
query {
    searchForState(state: "washington"){
        ...
    }
}
```

映射模板可能将状态作为参数：

```
"body":{
    "from":0,
    "size":50,
    "query" : {
        "multi_match" : {
            "query" : "$context.arguments.state",
            "fields" : ["city", "state"]
        }
    }
}
```

有关可以包含在 VTL 中的实用工具的列表，请参阅[访问请求标头](resolver-context-reference.md#aws-appsync-resolver-context-reference-util)。

# AWS AppSync Lambda 的解析器映射模板参考
<a name="resolver-mapping-template-reference-lambda"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

您可以使用 AWS AppSync 函数和解析器来调用位于您账户中的 Lambda 函数。您可以在将请求有效载荷和 Lambda 函数响应返回给客户端之前对其进行调整。您还可以使用映射模板来提示 AWS AppSync 要调用的操作的性质。本节介绍了支持的 Lambda 操作的各种映射模板。

## 请求映射模板
<a name="request-mapping-template"></a>

Lambda 请求映射模板可以处理与您的 Lambda 函数相关的字段：

```
{
  "version": string,
  "operation": Invoke|BatchInvoke,
  "payload": any type,
  "invocationType": RequestResponse|Event
}
```

以下是解析的 Lambda 请求映射模板的 JSON 架构表示形式：

```
{
  "definitions": {},
  "$schema": "https://json-schema.org/draft-06/schema#",
  "$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
  "type": "object",
  "properties": {
    "version": {
      "$id": "/properties/version",
      "type": "string",
      "enum": [
        "2018-05-29"
      ],
      "title": "The Mapping template version.",
      "default": "2018-05-29"
    },
    "operation": {
      "$id": "/properties/operation",
      "type": "string",
      "enum": [
        "Invoke",
        "BatchInvoke"
      ],
      "title": "The Mapping template operation.",
      "description": "What operation to execute.",
      "default": "Invoke"
    },
    "payload": {},
    "invocationType": {
      "$id": "/properties/invocationType",
      "type": "string",
      "enum": [
        "RequestResponse",
        "Event"
      ],
      "title": "The Mapping template invocation type.",
      "description": "What invocation type to execute.",
      "default": "RequestResponse"
    }
  },
  "required": [
    "version",
    "operation"
  ],
  "additionalProperties": false
}
```

以下示例使用了一个 `invoke` 操作，其有效载荷数据是 GraphQL 架构中的 `getPost` 字段以及来自上下文的参数：

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": $util.toJson($context.arguments)
  }
}
```

整个映射文档作为输入传递给您的 Lambda 函数，因此，上一示例现在如下所示：

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": {
      "id": "postId1"
    }
  }
}
```

### 版本
<a name="version"></a>

`version` 是所有请求映射模板通用的，用于定义模板使用的版本。`version` 为必填项，是一个静态值：

```
"version": "2018-05-29"
```

### 操作
<a name="operation"></a>

Lambda 数据来源允许您在 `operation` 字段中定义两个操作：`Invoke` 和 `BatchInvoke`。该`Invoke`操作允许 AWS AppSync 你为每个 GraphQL 字段解析器调用你的 Lambda 函数。 `BatchInvoke`指示 AWS AppSync 对当前 GraphQL 字段进行批量请求。`operation` 字段为必填项。

对于 `Invoke`，解析的请求映射模板与 Lambda 函数的输入有效载荷匹配。我们来修改上面的示例：

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
    "payload": {
      "arguments": $util.toJson($context.arguments)
    }
}
```

这已解析并传递给 Lambda 函数，可能如下所示：

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
    "payload": {
      "arguments": {
        "id": "postId1"
      }
    }
}
```

对于 `BatchInvoke`，映射模板应用于批次中的每个字段解析器。为简洁起见，将所有已解析的映射模板`payload`值 AWS AppSync 合并到与映射模板匹配的单个对象下的列表中。以下示例模板显示合并：

```
{
  "version": "2018-05-29",
  "operation": "BatchInvoke",
  "payload": $util.toJson($context)
}
```

此模板解析为以下映射文档：

```
{
  "version": "2018-05-29",
  "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"></a>

`payload` 字段是一个容器，用于将任何格式正确的 JSON 传递到 Lambda 函数。如果该`operation`字段设置为`BatchInvoke`，则 AWS AppSync 将现有`payload`值换成一个列表。`payload` 字段为可选项。

### 调用类型
<a name="async-invocation-type"></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 函数的输入有效载荷匹配。我们来修改上面的示例：

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "invocationType": "Event"
  "payload": {
    "arguments": $util.toJson($context.arguments)
  }
}
```

这已解析并传递给 Lambda 函数，可能如下所示：

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "invocationType": "Event",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

当该`BatchInvoke`操作与`Event`调用类型字段结合使用时，将以与上述相同的方式 AWS AppSync 合并字段解析器，然后将请求作为异步事件传递给您的 Lambda 函数，并以值列表的形式传送给您的 Lambda 函数。`payload`建议您对 `Event` 调用类型解析器禁用解析器缓存，因为如果出现缓存命中，这些解析器不会发送到 Lambda。

## 响应映射模板
<a name="response-mapping-template"></a>

与其他数据源一样，您的 Lambda 函数会向其发送一个必须转换为 GraphQL 类型的响应。 AWS AppSync 

Lambda 函数的结果是在通过 Velocity 模板语言 (VTL) `$context.result` 属性提供的 `context` 对象上设置的。

如果 Lambda 函数响应的形状与 GraphQL 类型的形状完全匹配，您可以使用以下响应映射模板转发响应：

```
$util.toJson($context.result)
```

没有必填字段，也没有形状限制应用于响应映射模板。但是，由于 GraphQL 是强类型化的，因此解析的映射模板必须与预期的 GraphQL 类型匹配。

## Lambda 函数批处理的响应
<a name="aws-appsync-resolver-mapping-template-reference-lambda-batched-response"></a>

如果 `operation` 字段设置为 `BatchInvoke`， AWS AppSync 预计从 Lambda 函数返回项目列表。 AWS AppSync 为了将每个结果映射回原始请求项，响应列表的大小和顺序必须匹配。可以在响应列表中包含 `null` 项目；`$ctx.result` 相应地设置为 *null*。

## 直接 Lambda 解析器
<a name="direct-lambda-resolvers"></a>

如果您想完全避免使用映射模板， AWS AppSync 可以为您的 Lambda 函数提供默认负载，并为 GraphQL 类型提供默认 Lambda 函数响应。您可以选择提供请求模板和响应模板，或者两者都不提供，然后进行相应的 AWS AppSync 处理。

### 直接 Lambda 请求映射模板
<a name="lambda-mapping-template-bypass-request"></a>

如果未提供请求映射模板，则 AWS AppSync 会将该`Context`对象作为操作直接发送到您的 Lambda 函数。`Invoke`有关 `Context` 对象结构的更多信息，请参阅 [AWS AppSync 解析器映射模板上下文参考](resolver-context-reference.md)。

### 直接 Lambda 响应映射模板
<a name="lambda-mapping-template-bypass-response"></a>

如果未提供响应映射模板，则在收到 Lambda 函数的响应后 AWS AppSync 执行以下两项操作之一。如果未提供请求映射模板，或者提供了版本为 `2018-05-29` 的请求映射模板，则该响应将相当于以下响应映射模板：

```
#if($ctx.error)
     $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
 #end
 $util.toJson($ctx.result)
```

如果您提供版本为 `2017-02-28` 的模板，则响应逻辑功能相当于以下响应映射模板：

```
$util.toJson($ctx.result)
```

从表面上看，映射模板绕过功能与使用某些映射模板类似，如前面的示例中所示。但在幕后，完全绕过了映射模板评估。由于绕过了模板评估步骤，在某些场景中，与具有需要评估的响应映射模板的 Lambda 函数相比，应用程序在响应期间可能会减少开销和延迟。

### 直接 Lambda 解析器响应中的自定义错误处理
<a name="lambda-mapping-template-bypass-errors"></a>

您可以通过引发自定义异常，自定义直接 Lambda 解析器调用的 Lambda 函数的错误响应。以下示例演示如何使用创建自定义异常 JavaScript：

```
class CustomException extends Error {
  constructor(message) {
    super(message);
    this.name = "CustomException";
  }
}
 
throw new CustomException("Custom message");
```

在引发异常时，`errorType` 和 `errorMessage` 分别是引发的自定义错误的 `name` 和 `message`。

如果`errorType`是`UnauthorizedException`，则 AWS AppSync返回默认消息 (`"You are not authorized to make this call."`)，而不是自定义消息。

以下代码片段是一个说明自定义 `errorType` 的示例 GraphQL 响应：

```
{
  "data": {
    "query": null
  },
  "errors": [
    {
      "path": [
        "query"
      ],
      "data": null,
      "errorType": "CustomException",
      "errorInfo": null,
      "locations": [
        {
          "line": 5,
          "column": 10,
          "sourceName": null
        }
      ],
      "message": "Custom Message"
    }
  ]
}
```

### 直接 Lambda 解析器：已启用批处理
<a name="lambda-resolvers-batching"></a>

您可以通过在解析器上配置 `maxBatchSize`，为直接 Lambda 解析器启用批处理。如果设置`0`为大于 D `maxBatchSize` irect Lambda 解析器的值，则会分批向您的 Lambda 函数 AWS AppSync 发送大小不超过的请求。`maxBatchSize`

如果在直接 Lambda 解析器上将 `maxBatchSize` 设置为 `0`，将关闭批处理。

有关 Lambda 解析器上的批处理的工作方式的更多信息，请参阅[高级使用案例：批处理](tutorial-lambda-resolvers.md#advanced-use-case-batching)。

#### 请求映射模板
<a name="lambda-resolvers-batching-request-template"></a>

启用批处理但未提供请求映射模板时， AWS AppSync 会将`Context`对象列表作为`BatchInvoke`操作直接发送到您的 Lambda 函数。

#### 响应映射模板
<a name="lambda-resolvers-batching-response-template"></a>

如果启用了批处理并且未提供响应映射模板，响应逻辑相当于以下响应映射模板：

```
#if( $context.result && $context.result.errorMessage )
      $utils.error($context.result.errorMessage, $context.result.errorType,
      $context.result.data)
#else
      $utils.toJson($context.result.data)
#end
```

Lambda 函数返回结果列表的顺序必须与发送的 `Context` 对象列表相同。您可以为特定结果提供 `errorMessage` 和 `errorType` 以返回各个错误。列表中的每个结果采用以下格式：

```
{
   "data" : { ... }, // your data
   "errorMessage" : { ... }, // optional, if included an error entry is added to the "errors" object in the AppSync response 
   "errorType" : { ... } // optional, the error type
}
```

**注意**  
目前忽略结果对象中的其他字段。

#### 处理来自 Lambda 的错误
<a name="lambda-resolvers-batching-error-handling"></a>

您可以通过在 Lambda 函数中引发异常或错误，为所有结果返回错误。如果批处理请求的负载请求或响应太大，Lambda 将返回错误。在这种情况下，您应该考虑减少 `maxBatchSize` 或减少响应负载大小。

有关处理各个错误的信息，请参阅[返回单个错误](tutorial-lambda-resolvers.md#returning-individual-errors)。

#### 示例 Lambda 函数
<a name="sample-lambda-function"></a>

通过使用下面的架构，您可以为 `Post.relatedPosts` 字段解析器创建直接 Lambda 解析器，并将 `maxBatchSize` 设置为大于 `0` 以启用批处理：

```
schema {
    query: Query
    mutation: Mutation
}

type Query {
    getPost(id:ID!): Post
    allPosts: [Post]
}

type Mutation {
    addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!
}

type Post {
    id: ID!
    author: String!
    title: String
    content: String
    url: String
    ups: Int
    downs: Int
    relatedPosts: [Post]
}
```

在以下查询中，将为批量请求调用 Lambda 函数以解析 `relatedPosts`：

```
query getAllPosts {
  allPosts {
    id
    relatedPosts {
      id
    }
  }
}
```

下面提供了 Lambda 函数的简单实施：

```
const posts = {
  1: {
    id: '1',
    title: 'First book',
    author: 'Author1',
    url: 'https://amazon.com/',
    content:
      'SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1',
    ups: '100',
    downs: '10',
  },
  2: {
    id: '2',
    title: 'Second book',
    author: 'Author2',
    url: 'https://amazon.com',
    content: 'SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT',
    ups: '100',
    downs: '10',
  },
  3: { id: '3', title: 'Third book', author: 'Author3', url: null, content: null, ups: null, downs: null },
  4: {
    id: '4',
    title: 'Fourth book',
    author: 'Author4',
    url: 'https://www.amazon.com/',
    content:
      'SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4',
    ups: '1000',
    downs: '0',
  },
  5: {
    id: '5',
    title: 'Fifth book',
    author: 'Author5',
    url: 'https://www.amazon.com/',
    content: 'SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT',
    ups: '50',
    downs: '0',
  },
}

const relatedPosts = {
  1: [posts['4']],
  2: [posts['3'], posts['5']],
  3: [posts['2'], posts['1']],
  4: [posts['2'], posts['1']],
  5: [],
}
exports.handler = async (event) => {
  console.log('event ->', event)
  // retrieve the ID of each post
  const ids = event.map((context) => context.source.id)
  // fetch the related posts for each post id
  const related = ids.map((id) => relatedPosts[id])

  // return the related posts; or an error if none were found
  return related.map((r) => {
    if (r.length > 0) {
      return { data: r }
    } else {
      return { data: null, errorMessage: 'Not found', errorType: 'ERROR' }
    }
  })
}
```

# AWS AppSync 的解析器映射模板参考 EventBridge
<a name="resolver-mapping-template-reference-eventbridge"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

与 EventBridge 数据源一起使用的 AWS AppSync 解析器映射模板允许您向 Amazon EventBridge 总线发送自定义事件。

## 请求映射模板
<a name="request-mapping-template"></a>

`PutEvents`请求映射模板允许您将多个自定义事件发送到 EventBridge事件总线。 映射文档具有以下结构：

```
{
    "version" : "2018-05-29", 
    "operation" : "PutEvents",
    "events" : [{}]
}
```

以下是用于的请求映射模板的示例 EventBridge：

```
{
    "version": "2018-05-29",
    "operation": "PutEvents",
    "events": [{
        "source": "com.mycompany.myapp",
        "detail": {
            "key1" : "value1",
            "key2" : "value2"
        },
        "detailType": "myDetailType1"
    },
    {
        "source": "com.mycompany.myapp",
        "detail": {
            "key3" : "value3",
            "key4" : "value4"
        },
        "detailType": "myDetailType2",
        "resources" : ["Resource1", "Resource2"],
        "time" : "2023-01-01T00:30:00.000Z"
    }
    
    ]
}
```

## 响应映射模板
<a name="response-mapping-template"></a>

如果`PutEvents`操作成功， EventBridge 则来自的响应将包含在`$ctx.result`：

```
#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
#end
  $util.toJson($ctx.result)
```

执行 `PutEvents` 操作时发生的错误（例如 `InternalExceptions` 或 `Timeouts`）将出现在 `$ctx.error` 中。有关常见错误 EventBridge的列表，请参阅[EventBridge 常见错误参考](https://docs.aws.amazon.com/eventbridge/latest/APIReference/CommonErrors.html)。

`result` 将采用以下格式：

```
{
    "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` 对象是一个有效的 JSON 对象，它具有以下字段：
  + `"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 `None`数据源的解析器映射模板参考
<a name="resolver-mapping-template-reference-none"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

与 *None* 类型的数据源一起使用的 AWS AppSync 解析器映射模板使您能够调整对 AWS AppSync 本地操作的请求。

## 请求映射模板
<a name="request-mapping-template"></a>

映射模板很简单，使您能够通过 `payload` 字段传递尽可能多的上下文信息。

```
{
   "version": string,
   "payload": any type
}
```

下面是请求映射模板的 JSON 架构表示形式（解析后）：

```
{
    "definitions": {},
    "$schema": "https://json-schema.org/draft-06/schema#",
    "$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
    "type": "object",
    "properties": {
        "version": {
            "$id": "/properties/version",
            "type": "string",
            "enum": [
                "2018-05-29"
            ],
            "title": "The Mapping template version.",
            "default": "2018-05-29"
        },
        "payload": {}
    },
    "required": [
        "version"
    ],
    "additionalProperties": false
}
```

以下是通过 VTL 上下文属性 `$context.arguments` 传递字段参数的示例：

```
{
    "version": "2018-05-29",
    "payload": $util.toJson($context.arguments)
}
```

`payload` 字段的值将转发到响应映射模板并可用于 VTL 上下文属性 (`$context.result`) 上。

这是一个表示 `payload` 字段的内插值的示例：

```
{
    "id": "postId1"
}
```

## 版本
<a name="version"></a>

`version` 字段是所有请求映射模板通用的，用于定义模板使用的版本。

 `version` 字段为必填项。

示例：

```
"version": "2018-05-29"
```

## 有效载荷
<a name="payload"></a>

`payload` 字段是一个容器，可用于将任何格式正确的 JSON 传递到响应映射模板。

 `payload` 字段为可选项。

## 响应映射模板
<a name="response-mapping-template"></a>

由于不存在任何数据来源，`payload` 字段的值将转发到响应映射模板并在 `context` 对象上设置（此对象可通过 VTL `$context.result` 属性提供）。

如果 `payload` 字段值的形状与 GraphQL 类型的形状完全相符，您可以使用以下响应映射模板转发响应：

```
$util.toJson($context.result)
```

没有必填字段，也没有形状限制应用于响应映射模板。但是，由于 GraphQL 是强类型化的，因此解析的映射模板必须与预期的 GraphQL 类型匹配。

# AWS AppSync HTTP 的解析器映射模板参考
<a name="resolver-mapping-template-reference-http"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

 AWS AppSync HTTP 解析器映射模板使您可以将来自的请求发送 AWS AppSync 到任何 HTTP 端点，并将来自您的 HTTP 端点的响应发送回到 AWS AppSync。通过使用映射模板，您可以提供 AWS AppSync 有关要调用的操作性质的提示。本节介绍用于支持的 HTTP 解析器的不同映射模板。

## 请求映射模板
<a name="request-mapping-template"></a>

```
{
    "version": "2018-05-29",
    "method": "PUT|POST|GET|DELETE|PATCH",
    "params": {
        "query": Map,
        "headers": Map,
        "body": any
    },
    "resourcePath": string
}
```

解析 HTTP 请求映射模板后，请求映射模板的 JSON 架构表现形式如下所示：

```
{
    "$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
    "type": "object",
    "properties": {
        "version": {
        "$id": "/properties/version",
        "type": "string",
        "title": "The Version Schema ",
        "default": "",
        "examples": [
            "2018-05-29"
        ],
        "enum": [
            "2018-05-29"
        ]
        },
        "method": {
        "$id": "/properties/method",
        "type": "string",
        "title": "The Method Schema ",
        "default": "",
        "examples": [
            "PUT|POST|GET|DELETE|PATCH"
        ],
        "enum": [
            "PUT",
            "PATCH",
            "POST",
            "DELETE",
            "GET"
        ]
        },
        "params": {
        "$id": "/properties/params",
        "type": "object",
        "properties": {
            "query": {
            "$id": "/properties/params/properties/query",
            "type": "object"
            },
            "headers": {
            "$id": "/properties/params/properties/headers",
            "type": "object"
            },
            "body": {
            "$id": "/properties/params/properties/body",
            "type": "string",
            "title": "The Body Schema ",
            "default": "",
            "examples": [
                ""
            ]
            }
        }
        },
        "resourcePath": {
        "$id": "/properties/resourcePath",
        "type": "string",
        "title": "The Resourcepath Schema ",
        "default": "",
        "examples": [
            ""
        ]
        }
    },
    "required": [
        "version",
        "method",
        "resourcePath"
    ]
}
```

以下是 HTTP POST 请求的示例，具有 `text/plain` 正文：

```
{
    "version": "2018-05-29",
    "method": "POST",
    "params": {
        "headers":{
        "Content-Type":"text/plain"
        },
        "body":"this is an example of text body"
    },
    "resourcePath": "/"
}
```

## 版本
<a name="version"></a>

**注意**  
这仅适用于请求映射模板。

定义模板使用的版本。`version` 对于所有请求映射模板都相同且是必需的。

```
"version": "2018-05-29"
```

## 方法
<a name="method"></a>

**注意**  
这仅适用于请求映射模板。

 AWS AppSync 发送到 HTTP 端点的 HTTP 方法或动词（GET、POST、PUT、PATCH 或 DELETE）。

```
"method": "PUT"
```

## ResourcePath
<a name="resourcepath"></a>

**注意**  
这仅适用于请求映射模板。

您要访问的资源路径。资源路径与 HTTP 数据源中的端点一起构成 AWS AppSync 服务向其发出请求的 URL。

```
"resourcePath": "/v1/users"
```

评估映射模板时，此路径作为 HTTP 请求的一部分发送，包括 HTTP 终端节点。例如，上一个示例可能会转换为如下所示：

```
PUT <endpoint>/v1/users
```

## 参数字段
<a name="params-field"></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"></a>

请参见[此处](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-http-resolvers.html)的示例。

# AWS AppSync 识别的 HTTPS 终端节点证书颁发机构 (CA)
<a name="http-cert-authorities"></a>

**注意**  
Let's Encrypt 通过 *identrust* and *isrgrootx1* 证书进行验证。如果您使用 Let's Encrypt，则无需采取任何措施。

目前，在使用 HTTPS 时，HTTP 解析器不支持自签名证书。AWS在解析 HTTPS 的 SSL/TLS 证书时，AppSync 识别以下证书颁发机构：


**AWS AppSync 中的已知根证书**  

| 名称 | 日期 | SHA1 指纹 | 
| --- | --- | --- | 
| digicertassuredidrootca | 2018 年 4 月 21 日 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| trustcenterclass2caii | 2018 年 4 月 21 日 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| thawtepremiumserverca | 2018 年 4 月 21 日 | E0:AB:05:94:20:72:54:93:05:60:62:02:36:70:F7:CD:2E:FC:66:66 | 
| cia-crt-g3-02-ca | 2016 年 11 月 23 日 | 96:4A:BB:A7:BD:DA:FC:97:34:C0:0A:2D:F0:05:98:F7:E6:C6:6F:09 | 
| swisssignplatinumg2ca | 2018 年 4 月 21 日 | 56:E0:FA:C0:3B:8F:18:23:55:18:E5:D3:11:CA:E8:C2:43:31:AB:66 | 
| swisssignsilverg2ca | 2018 年 4 月 21 日 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| thawteserverca | 2018 年 4 月 21 日 | 9F:AD:91:A6:CE:6A:C6:C5:00:47:C4:4E:C9:D4:A5:0D:92:D8:49:79 | 
| equifaxsecureebusinessca1 | 2018 年 4 月 21 日 | AE:E6:3D:70:E3:76:FB:C7:3A:EB:B0:A1:C1:D4:C4:7A:A7:40:B3:F4 | 
| securetrustca | 2018 年 4 月 21 日 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| utnuserfirstclientauthemailca | 2018 年 4 月 21 日 | B1:72:B1:A5:6D:95:F9:1F:E5:02:87:E1:4D:37:EA:6A:44:63:76:8A | 
| thawtepersonalfreemailca | 2018 年 4 月 21 日 | E6:18:83:AE:84:CA:C1:C1:CD:52:AD:E8:E9:25:2B:45:A6:4F:B7:E2 | 
| affirmtrustnetworkingca | 2018 年 4 月 21 日 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| entrustevca | 2018 年 4 月 21 日 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| utnuserfirsthardwareca | 2018 年 4 月 21 日 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| certumca | 2018 年 4 月 21 日 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| addtrustclass1ca | 2018 年 4 月 21 日 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| entrustrootcag2 | 2018 年 4 月 21 日 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| equifaxsecureca | 2018 年 4 月 21 日 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| quovadisrootca3 | 2018 年 4 月 21 日 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| quovadisrootca2 | 2018 年 4 月 21 日 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| digicertglobalrootg2 | 2018 年 4 月 21 日 | DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4 | 
| digicerthighassuranceevrootca | 2018 年 4 月 21 日 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| secomvalicertclass1ca | 2018 年 4 月 21 日 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| equifaxsecureglobalebusinessca1 | 2018 年 4 月 21 日 | 3A:74:CB:7A:47:DB:70:DE:89:1F:24:35:98:64:B8:2D:82:BD:1A:36 | 
| geotrustuniversalca | 2018 年 4 月 21 日 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| deprecateditsecca | 2012 年 1 月 27 日 | 12:12:0B:03:0E:15:14:54:F4:DD:B3:F5:DE:13:6E:83:5A:29:72:9D | 
| verisignclass3ca | 2018 年 4 月 21 日 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| thawteprimaryrootcag3 | 2018 年 4 月 21 日 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| thawteprimaryrootcag2 | 2018 年 4 月 21 日 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| deutschetelekomrootca2 | 2018 年 4 月 21 日 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| buypassclass3ca | 2018 年 4 月 21 日 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| utnuserfirstobjectca | 2018 年 4 月 21 日 | E1:2D:FB:4B:41:D7:D9:C3:2B:30:51:4B:AC:1D:81:D8:38:5E:2D:46 | 
| geotrustprimaryca | 2018 年 4 月 21 日 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| buypassclass2ca | 2018 年 4 月 21 日 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| baltimorecodesigningca | 2018 年 4 月 21 日 | 30:46:D8:C8:88:FF:69:30:C3:4A:FC:CD:49:27:08:7C:60:56:7B:0D | 
| verisignclass1ca | 2018 年 4 月 21 日 | CE:6A:64:A3:09:E4:2F:BB:D9:85:1C:45:3E:64:09:EA:E8:7D:60:F1 | 
| baltimorecybertrustca | 2018 年 4 月 21 日 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| starfieldclass2ca | 2018 年 4 月 21 日 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| camerfirmachamberscommerceca | 2018 年 4 月 21 日 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| ttelesecglobalrootclass3ca | 2018 年 4 月 21 日 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| verisignclass3g5ca | 2018 年 4 月 21 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| ttelesecglobalrootclass2ca | 2018 年 4 月 21 日 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| trustcenteruniversalcai | 2018 年 4 月 21 日 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| verisignclass3g4ca | 2018 年 4 月 21 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignclass3g3ca | 2018 年 4 月 21 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| xrampglobalca | 2018 年 4 月 21 日 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| amzninternalrootca | 2008 年 12 月 12 日 | A7:B7:F6:15:8A:FF:1E:C8:85:13:38:BC:93:EB:A2:AB:A4:09:EF:06 | 
| certplusclass3pprimaryca | 2018 年 4 月 21 日 | 21:6B:2A:29:E6:2A:00:CE:82:01:46:D8:24:41:41:B9:25:11:B2:79 | 
| certumtrustednetworkca | 2018 年 4 月 21 日 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| verisignclass3g2ca | 2018 年 4 月 21 日 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| globalsignr3ca | 2018 年 4 月 21 日 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| utndatacorpsgcca | 2018 年 4 月 21 日 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| secomscrootca2 | 2018 年 4 月 21 日 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| gtecybertrustglobalca | 2018 年 4 月 21 日 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| secomscrootca1 | 2018 年 4 月 21 日 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| affirmtrustcommercialca | 2018 年 4 月 21 日 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| trustcenterclass4caii | 2018 年 4 月 21 日 | A6:9A:91:FD:05:7F:13:6A:42:63:0B:B1:76:0D:2D:51:12:0C:16:50 | 
| verisignuniversalrootca | 2018 年 4 月 21 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| globalsignr2ca | 2018 年 4 月 21 日 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| certplusclass2primaryca | 2018 年 4 月 21 日 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| digicertglobalrootca | 2018 年 4 月 21 日 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| globalsignca | 2018 年 4 月 21 日 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| thawteprimaryrootca | 2018 年 4 月 21 日 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| starfieldrootg2ca | 2018 年 4 月 21 日 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| geotrustglobalca | 2018 年 4 月 21 日 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| soneraclass2ca | 2018 年 4 月 21 日 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| verisigntsaca | 2018 年 4 月 21 日 | 20:CE:B1:F0:F5:1C:0E:19:A9:F3:8D:B1:AA:8E:03:8C:AA:7A:C7:01 | 
| soneraclass1ca | 2018 年 4 月 21 日 | 07:47:22:01:99:CE:74:B9:7C:B0:3D:79:B2:64:A2:C8:55:E9:33:FF | 
| quovadisrootca | 2018 年 4 月 21 日 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| affirmtrustpremiumeccca | 2018 年 4 月 21 日 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| starfieldservicesrootg2ca | 2018 年 4 月 21 日 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| valicertclass2ca | 2018 年 4 月 21 日 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| comodoaaaca | 2018 年 4 月 21 日 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| aolrootca2 | 2018 年 4 月 21 日 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| keynectisrootca | 2018 年 4 月 21 日 | 9C:61:5C:4D:4D:85:10:3A:53:26:C2:4D:BA:EA:E4:A2:D2:D5:CC:97 | 
| addtrustqualifiedca | 2018 年 4 月 21 日 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| aolrootca1 | 2018 年 4 月 21 日 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| verisignclass2g3ca | 2018 年 4 月 21 日 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| addtrustexternalca | 2018 年 4 月 21 日 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| verisignclass2g2ca | 2018 年 4 月 21 日 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| geotrustprimarycag3 | 2018 年 4 月 21 日 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| geotrustprimarycag2 | 2018 年 4 月 21 日 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| swisssigngoldg2ca | 2018 年 4 月 21 日 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| entrust2048ca | 2018 年 4 月 21 日 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| chunghwaepkirootca | 2018 年 4 月 21 日 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| camerfirmachambersignca | 2018 年 4 月 21 日 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| camerfirmachambersca | 2018 年 4 月 21 日 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| godaddyclass2ca | 2018 年 4 月 21 日 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| affirmtrustpremiumca | 2018 年 4 月 21 日 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| verisignclass1g3ca | 2018 年 4 月 21 日 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| secomevrootca1 | 2018 年 4 月 21 日 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| verisignclass1g2ca | 2018 年 4 月 21 日 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| amzninternalinfoseccag3 | 2015 年 2 月 27 日 | B9:B1:CA:38:F7:BF:9C:D2:D4:95:E7:B6:5E:75:32:9B:A8:78:2E:F6 | 
| cia-crt-g3-01-ca | 2016 年 11 月 23 日 | 2B:EE:2C:BA:A3:1D:B5:FE:60:40:41:95:08:ED:46:82:39:4D:ED:E2 | 
| godaddyrootg2ca | 2018 年 4 月 21 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| digicertassuredidrootca | 2018 年 4 月 21 日 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| microseceszignorootca2009 | 2018 年 4 月 21 日 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| affirmtrustcommercial | 2018 年 4 月 21 日 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| comodoecccertificationauthority | 2018 年 4 月 21 日 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| cadisigrootr2 | 2018 年 4 月 21 日 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| swisssignsilvercag2 | 2018 年 4 月 21 日 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| securetrustca | 2018 年 4 月 21 日 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| cadisigrootr1 | 2018 年 4 月 21 日 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| accvraiz1 | 2018 年 4 月 21 日 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| entrustrootcertificationauthority | 2018 年 4 月 21 日 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| camerfirmaglobalchambersignroot | 2018 年 4 月 21 日 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| dstacescax6 | 2018 年 4 月 21 日 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| identrustpublicsectorrootca1 | 2018 年 4 月 21 日 | BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD | 
| starfieldrootcertificateauthorityg2 | 2018 年 4 月 21 日 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| secureglobalca | 2018 年 4 月 21 日 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| eecertificationcentrerootca | 2018 年 4 月 21 日 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| opentrustrootcag3 | 2018 年 4 月 21 日 | 6E:26:64:F3:56:BF:34:55:BF:D1:93:3F:7C:01:DE:D8:13:DA:8A:A6 | 
| teliasonerarootcav1 | 2018 年 4 月 21 日 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| autoridaddecertificacionfirmaprofesionalcifa62634068 | 2018 年 4 月 21 日 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| opentrustrootcag2 | 2018 年 4 月 21 日 | 79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B | 
| opentrustrootcag1 | 2018 年 4 月 21 日 | 79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E | 
| globalsigneccrootcar5 | 2018 年 4 月 21 日 | 1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA | 
| globalsigneccrootcar4 | 2018 年 4 月 21 日 | 69:69:56:2E:40:80:F4:24:A1:E7:19:9F:14:BA:F3:EE:58:AB:6A:BB | 
| izenpecom | 2018 年 4 月 21 日 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| turktrustelektroniksertifikahizmetsaglayicisih5 | 2018 年 4 月 21 日 | C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB | 
| gdcatrustauthr5root | 2018 年 4 月 21 日 | 0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4 | 
| dtrustrootclass3ca22009 | 2018 年 4 月 21 日 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| quovadisrootca3 | 2018 年 4 月 21 日 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| quovadisrootca2 | 2018 年 4 月 21 日 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| geotrustprimarycertificationauthorityg3 | 2018 年 4 月 21 日 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| geotrustprimarycertificationauthorityg2 | 2018 年 4 月 21 日 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| oistewisekeyglobalrootgbca | 2018 年 4 月 21 日 | 0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED | 
| addtrustexternalroot | 2018 年 4 月 21 日 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| chambersofcommerceroot2008 | 2018 年 4 月 21 日 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| digicertglobalrootg3 | 2018 年 4 月 21 日 | 7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E | 
| comodoaaaservicesroot | 2018 年 4 月 21 日 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| digicertglobalrootg2 | 2018 年 4 月 21 日 | DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4 | 
| certinomisrootca | 2018 年 4 月 21 日 | 9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8 | 
| oistewisekeyglobalrootgaca | 2018 年 4 月 21 日 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| dstrootcax3 | 2018 年 4 月 21 日 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| certigna | 2018 年 4 月 21 日 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| digicerthighassuranceevrootca | 2018 年 4 月 21 日 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| soneraclass2rootca | 2018 年 4 月 21 日 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| trustcorrootcertca2 | 2018 年 4 月 21 日 | B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0 | 
| usertrustrsacertificationauthority | 2018 年 4 月 21 日 | 2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E | 
| trustcorrootcertca1 | 2018 年 4 月 21 日 | FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A | 
| geotrustuniversalca | 2018 年 4 月 21 日 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| certsignrootca | 2018 年 4 月 21 日 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| amazonrootca4 | 2018 年 4 月 21 日 | F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE | 
| amazonrootca3 | 2018 年 4 月 21 日 | 0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E | 
| amazonrootca2 | 2018 年 4 月 21 日 | 5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A | 
| verisignuniversalrootcertificationauthority | 2018 年 4 月 21 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| amazonrootca1 | 2018 年 4 月 21 日 | 8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16 | 
| networksolutionscertificateauthority | 2018 年 4 月 21 日 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| thawteprimaryrootcag3 | 2018 年 4 月 21 日 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| affirmtrustnetworking | 2018 年 4 月 21 日 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| thawteprimaryrootcag2 | 2018 年 4 月 21 日 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| trustcoreca1 | 2018 年 4 月 21 日 | 58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD | 
| deutschetelekomrootca2 | 2018 年 4 月 21 日 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| godaddyrootcertificateauthorityg2 | 2018 年 4 月 21 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| entrustrootcertificationauthorityec1 | 2018 年 4 月 21 日 | 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 | 
| szafirrootca2 | 2018 年 4 月 21 日 | E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE | 
| tubitakkamusmsslkoksertifikasisurum1 | 2018 年 4 月 21 日 | 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA | 
| buypassclass3rootca | 2018 年 4 月 21 日 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| comodorsacertificationauthority | 2018 年 4 月 21 日 | AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4 | 
| netlockaranyclassgoldfotanusitvany | 2018 年 4 月 21 日 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| securitycommunicationrootca2 | 2018 年 4 月 21 日 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| dtrustrootclass3ca2ev2009 | 2018 年 4 月 21 日 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| starfieldclass2ca | 2018 年 4 月 21 日 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| pscprocert | 2018 年 4 月 21 日 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| actalisauthenticationrootca | 2018 年 4 月 21 日 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| staatdernederlandenrootcag3 | 2018 年 4 月 21 日 | D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC | 
| cfcaevroot | 2018 年 4 月 21 日 | E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 | 
| digicerttrustedrootg4 | 2018 年 4 月 21 日 | DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4 | 
| staatdernederlandenrootcag2 | 2018 年 4 月 21 日 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| securitycommunicationevrootca1 | 2018 年 4 月 21 日 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| globalsignrootcar3 | 2018 年 4 月 21 日 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| globalsignrootcar2 | 2018 年 4 月 21 日 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| certumtrustednetworkca2 | 2018 年 4 月 21 日 | D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92 | 
| acraizfnmtrcm | 2018 年 4 月 21 日 | EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20 | 
| hellenicacademicandresearchinstitutionseccrootca2015 | 2018 年 4 月 21 日 | 9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66 | 
| certplusrootcag2 | 2018 年 4 月 21 日 | 4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A | 
| twcarootcertificationauthority | 2018 年 4 月 21 日 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| twcaglobalrootca | 2018 年 4 月 21 日 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| certplusrootcag1 | 2018 年 4 月 21 日 | 22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66 | 
| geotrustuniversalca2 | 2018 年 4 月 21 日 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| baltimorecybertrustroot | 2018 年 4 月 21 日 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| buypassclass2rootca | 2018 年 4 月 21 日 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| certumtrustednetworkca | 2018 年 4 月 21 日 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| digicertassuredidrootg3 | 2018 年 4 月 21 日 | F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89 | 
| digicertassuredidrootg2 | 2018 年 4 月 21 日 | A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F | 
| isrgrootx1 | 2018 年 4 月 21 日 | CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8 | 
| entrustnetpremium2048secureserverca | 2018 年 4 月 21 日 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| certplusclass2primaryca | 2018 年 4 月 21 日 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| digicertglobalrootca | 2018 年 4 月 21 日 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| entrustrootcertificationauthorityg2 | 2018 年 4 月 21 日 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| starfieldservicesrootcertificateauthorityg2 | 2018 年 4 月 21 日 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| thawteprimaryrootca | 2018 年 4 月 21 日 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| atostrustedroot2011 | 2018 年 4 月 21 日 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| geotrustglobalca | 2018 年 4 月 21 日 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| luxtrustglobalroot2 | 2018 年 4 月 21 日 | 1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F | 
| etugracertificationauthority | 2018 年 4 月 21 日 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| visaecommerceroot | 2018 年 4 月 21 日 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| quovadisrootca | 2018 年 4 月 21 日 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| identrustcommercialrootca1 | 2018 年 4 月 21 日 | DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 | 
| staatdernederlandenevrootca | 2018 年 4 月 21 日 | 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB | 
| ttelesecglobalrootclass3 | 2018 年 4 月 21 日 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| ttelesecglobalrootclass2 | 2018 年 4 月 21 日 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| comodocertificationauthority | 2018 年 4 月 21 日 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| securitycommunicationrootca | 2018 年 4 月 21 日 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| quovadisrootca3g3 | 2018 年 4 月 21 日 | 48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D | 
| xrampglobalcaroot | 2018 年 4 月 21 日 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| securesignrootca11 | 2018 年 4 月 21 日 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| affirmtrustpremium | 2018 年 4 月 21 日 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| globalsignrootca | 2018 年 4 月 21 日 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| swisssigngoldcag2 | 2018 年 4 月 21 日 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| quovadisrootca2g3 | 2018 年 4 月 21 日 | 09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36 | 
| affirmtrustpremiumecc | 2018 年 4 月 21 日 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| geotrustprimarycertificationauthority | 2018 年 4 月 21 日 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| quovadisrootca1g3 | 2018 年 4 月 21 日 | 1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67 | 
| hongkongpostrootca1 | 2018 年 4 月 21 日 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| usertrustecccertificationauthority | 2018 年 4 月 21 日 | D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0 | 
| cybertrustglobalroot | 2018 年 4 月 21 日 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| godaddyclass2ca | 2018 年 4 月 21 日 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| hellenicacademicandresearchinstitutionsrootca2015 | 2018 年 4 月 21 日 | 01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6 | 
| ecacc | 2018 年 4 月 21 日 | 28:90:3A:63:5B:52:80:FA:E6:77:4C:0B:6D:A7:D6:BA:A6:4A:F2:E8 | 
| hellenicacademicandresearchinstitutionsrootca2011 | 2018 年 4 月 21 日 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| verisignclass3publicprimarycertificationauthorityg5 | 2018 年 4 月 21 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| verisignclass3publicprimarycertificationauthorityg4 | 2018 年 4 月 21 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignclass3publicprimarycertificationauthorityg3 | 2018 年 4 月 21 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| trustisfpsrootca | 2018 年 4 月 21 日 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| epkirootcertificationauthority | 2018 年 4 月 21 日 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| globalchambersignroot2008 | 2018 年 4 月 21 日 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| camerfirmachambersofcommerceroot | 2018 年 4 月 21 日 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| mozillacert81.pem | 2014 年 3 月 13 日 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| mozillacert99.pem | 2014 年 3 月 13 日 | F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33 | 
| mozillacert145.pem | 2014 年 3 月 13 日 | 10:1D:FA:3F:D5:0B:CB:BB:9B:B5:60:0C:19:55:A4:1A:F4:73:3A:04 | 
| mozillacert37.pem | 2014 年 3 月 13 日 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| mozillacert4.pem | 2014 年 3 月 13 日 | E3:92:51:2F:0A:CF:F5:05:DF:F6:DE:06:7F:75:37:E1:65:EA:57:4B | 
| mozillacert70.pem | 2014 年 3 月 13 日 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| mozillacert88.pem | 2014 年 3 月 13 日 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| mozillacert134.pem | 2014 年 3 月 13 日 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| mozillacert26.pem | 2014 年 3 月 13 日 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| mozillacert77.pem | 2014 年 3 月 13 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| mozillacert123.pem | 2014 年 3 月 13 日 | 2A:B6:28:48:5E:78:FB:F3:AD:9E:79:10:DD:6B:DF:99:72:2C:96:E5 | 
| mozillacert15.pem | 2014 年 3 月 13 日 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| mozillacert66.pem | 2014 年 3 月 13 日 | DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34 | 
| mozillacert112.pem | 2014 年 3 月 13 日 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| mozillacert55.pem | 2014 年 3 月 13 日 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| mozillacert101.pem | 2014 年 3 月 13 日 | 99:A6:9B:E6:1A:FE:88:6B:4D:2B:82:00:7C:B8:54:FC:31:7E:15:39 | 
| mozillacert119.pem | 2014 年 3 月 13 日 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| mozillacert44.pem | 2014 年 3 月 13 日 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| mozillacert108.pem | 2014 年 3 月 13 日 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| mozillacert95.pem | 2014 年 3 月 13 日 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| mozillacert141.pem | 2014 年 3 月 13 日 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| mozillacert33.pem | 2014 年 3 月 13 日 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| mozillacert0.pem | 2014 年 3 月 13 日 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| mozillacert84.pem | 2014 年 3 月 13 日 | D3:C0:63:F2:19:ED:07:3E:34:AD:5D:75:0B:32:76:29:FF:D5:9A:F2 | 
| mozillacert130.pem | 2014 年 3 月 13 日 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| mozillacert148.pem | 2014 年 3 月 13 日 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| mozillacert22.pem | 2014 年 3 月 13 日 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| mozillacert7.pem | 2014 年 3 月 13 日 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| mozillacert73.pem | 2014 年 3 月 13 日 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| mozillacert137.pem | 2014 年 3 月 13 日 | 4A:65:D5:F4:1D:EF:39:B8:B8:90:4A:4A:D3:64:81:33:CF:C7:A1:D1 | 
| mozillacert11.pem | 2014 年 3 月 13 日 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| mozillacert29.pem | 2014 年 3 月 13 日 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| mozillacert62.pem | 2014 年 3 月 13 日 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| mozillacert126.pem | 2014 年 3 月 13 日 | 25:01:90:19:CF:FB:D9:99:1C:B7:68:25:74:8D:94:5F:30:93:95:42 | 
| mozillacert18.pem | 2014 年 3 月 13 日 | 79:98:A3:08:E1:4D:65:85:E6:C2:1E:15:3A:71:9F:BA:5A:D3:4A:D9 | 
| mozillacert51.pem | 2014 年 3 月 13 日 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| mozillacert69.pem | 2014 年 3 月 13 日 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| mozillacert115.pem | 2014 年 3 月 13 日 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| mozillacert40.pem | 2014 年 3 月 13 日 | 80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5 | 
| mozillacert58.pem | 2014 年 3 月 13 日 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| mozillacert104.pem | 2014 年 3 月 13 日 | 4F:99:AA:93:FB:2B:D1:37:26:A1:99:4A:CE:7F:F0:05:F2:93:5D:1E | 
| mozillacert91.pem | 2014 年 3 月 13 日 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| mozillacert47.pem | 2014 年 3 月 13 日 | 1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96 | 
| mozillacert80.pem | 2014 年 3 月 13 日 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| mozillacert98.pem | 2014 年 3 月 13 日 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| mozillacert144.pem | 2014 年 3 月 13 日 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| mozillacert36.pem | 2014 年 3 月 13 日 | 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D | 
| mozillacert3.pem | 2014 年 3 月 13 日 | 87:9F:4B:EE:05:DF:98:58:3B:E3:60:D6:33:E7:0D:3F:FE:98:71:AF | 
| mozillacert87.pem | 2014 年 3 月 13 日 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| mozillacert133.pem | 2014 年 3 月 13 日 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| mozillacert25.pem | 2014 年 3 月 13 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| mozillacert76.pem | 2014 年 3 月 13 日 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| mozillacert122.pem | 2014 年 3 月 13 日 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| mozillacert14.pem | 2014 年 3 月 13 日 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| mozillacert65.pem | 2014 年 3 月 13 日 | 69:BD:8C:F4:9C:D3:00:FB:59:2E:17:93:CA:55:6A:F3:EC:AA:35:FB | 
| mozillacert111.pem | 2014 年 3 月 13 日 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| mozillacert129.pem | 2014 年 3 月 13 日 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| mozillacert54.pem | 2014 年 3 月 13 日 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| mozillacert100.pem | 2014 年 3 月 13 日 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| mozillacert118.pem | 2014 年 3 月 13 日 | 7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45 | 
| mozillacert151.pem | 2014 年 3 月 13 日 | AC:ED:5F:65:53:FD:25:CE:01:5F:1F:7A:48:3B:6A:74:9F:61:78:C6 | 
| mozillacert43.pem | 2014 年 3 月 13 日 | F9:CD:0E:2C:DA:76:24:C1:8F:BD:F0:F0:AB:B6:45:B8:F7:FE:D5:7A | 
| mozillacert107.pem | 2014 年 3 月 13 日 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| mozillacert94.pem | 2014 年 3 月 13 日 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| mozillacert140.pem | 2014 年 3 月 13 日 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| mozillacert32.pem | 2014 年 3 月 13 日 | 60:D6:89:74:B5:C2:65:9E:8A:0F:C1:88:7C:88:D2:46:69:1B:18:2C | 
| mozillacert83.pem | 2014 年 3 月 13 日 | A0:73:E5:C5:BD:43:61:0D:86:4C:21:13:0A:85:58:57:CC:9C:EA:46 | 
| mozillacert147.pem | 2014 年 3 月 13 日 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| mozillacert21.pem | 2014 年 3 月 13 日 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| mozillacert39.pem | 2014 年 3 月 13 日 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| mozillacert6.pem | 2014 年 3 月 13 日 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| mozillacert72.pem | 2014 年 3 月 13 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| mozillacert136.pem | 2014 年 3 月 13 日 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert10.pem | 2014 年 3 月 13 日 | 5F:3A:FC:0A:8B:64:F6:86:67:34:74:DF:7E:A9:A2:FE:F9:FA:7A:51 | 
| mozillacert28.pem | 2014 年 3 月 13 日 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| mozillacert61.pem | 2014 年 3 月 13 日 | E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84 | 
| mozillacert79.pem | 2014 年 3 月 13 日 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| mozillacert125.pem | 2014 年 3 月 13 日 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert17.pem | 2014 年 3 月 13 日 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| mozillacert50.pem | 2014 年 3 月 13 日 | 8C:96:BA:EB:DD:2B:07:07:48:EE:30:32:66:A0:F3:98:6E:7C:AE:58 | 
| mozillacert68.pem | 2014 年 3 月 13 日 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| mozillacert114.pem | 2014 年 3 月 13 日 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| mozillacert57.pem | 2014 年 3 月 13 日 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| mozillacert103.pem | 2014 年 3 月 13 日 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| mozillacert90.pem | 2014 年 3 月 13 日 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| mozillacert46.pem | 2014 年 3 月 13 日 | 40:9D:4B:D9:17:B5:5C:27:B6:9B:64:CB:98:22:44:0D:CD:09:B8:89 | 
| mozillacert97.pem | 2014 年 3 月 13 日 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| mozillacert143.pem | 2014 年 3 月 13 日 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| mozillacert35.pem | 2014 年 3 月 13 日 | 2A:C8:D5:8B:57:CE:BF:2F:49:AF:F2:FC:76:8F:51:14:62:90:7A:41 | 
| mozillacert2.pem | 2014 年 3 月 13 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| mozillacert86.pem | 2014 年 3 月 13 日 | 74:2C:31:92:E6:07:E4:24:EB:45:49:54:2B:E1:BB:C5:3E:61:74:E2 | 
| mozillacert132.pem | 2014 年 3 月 13 日 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| mozillacert24.pem | 2014 年 3 月 13 日 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| mozillacert9.pem | 2014 年 3 月 13 日 | F4:8B:11:BF:DE:AB:BE:94:54:20:71:E6:41:DE:6B:BE:88:2B:40:B9 | 
| mozillacert75.pem | 2014 年 3 月 13 日 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| mozillacert121.pem | 2014 年 3 月 13 日 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| mozillacert139.pem | 2014 年 3 月 13 日 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| mozillacert13.pem | 2014 年 3 月 13 日 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| mozillacert64.pem | 2014 年 3 月 13 日 | 62:7F:8D:78:27:65:63:99:D2:7D:7F:90:44:C9:FE:B3:F3:3E:FA:9A | 
| mozillacert110.pem | 2014 年 3 月 13 日 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| mozillacert128.pem | 2014 年 3 月 13 日 | A9:E9:78:08:14:37:58:88:F2:05:19:B0:6D:2B:0D:2B:60:16:90:7D | 
| mozillacert53.pem | 2014 年 3 月 13 日 | 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74 | 
| mozillacert117.pem | 2014 年 3 月 13 日 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| mozillacert150.pem | 2014 年 3 月 13 日 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| mozillacert42.pem | 2014 年 3 月 13 日 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| mozillacert106.pem | 2014 年 3 月 13 日 | E7:A1:90:29:D3:D5:52:DC:0D:0F:C6:92:D3:EA:88:0D:15:2E:1A:6B | 
| mozillacert93.pem | 2014 年 3 月 13 日 | 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17 | 
| mozillacert31.pem | 2014 年 3 月 13 日 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| mozillacert49.pem | 2014 年 3 月 13 日 | 61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71 | 
| mozillacert82.pem | 2014 年 3 月 13 日 | 2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3 | 
| mozillacert146.pem | 2014 年 3 月 13 日 | 21:FC:BD:8E:7F:6C:AF:05:1B:D1:B3:43:EC:A8:E7:61:47:F2:0F:8A | 
| mozillacert20.pem | 2014 年 3 月 13 日 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert38.pem | 2014 年 3 月 13 日 | CB:A1:C5:F8:B0:E3:5E:B8:B9:45:12:D3:F9:34:A2:E9:06:10:D3:36 | 
| mozillacert5.pem | 2014 年 3 月 13 日 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| mozillacert71.pem | 2014 年 3 月 13 日 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| mozillacert89.pem | 2014 年 3 月 13 日 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| mozillacert135.pem | 2014 年 3 月 13 日 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| mozillacert27.pem | 2014 年 3 月 13 日 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| mozillacert60.pem | 2014 年 3 月 13 日 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| mozillacert78.pem | 2014 年 3 月 13 日 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| mozillacert124.pem | 2014 年 3 月 13 日 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| mozillacert16.pem | 2014 年 3 月 13 日 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| mozillacert67.pem | 2014 年 3 月 13 日 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| mozillacert113.pem | 2014 年 3 月 13 日 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| mozillacert56.pem | 2014 年 3 月 13 日 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| mozillacert102.pem | 2014 年 3 月 13 日 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| mozillacert45.pem | 2014 年 3 月 13 日 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert109.pem | 2014 年 3 月 13 日 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| mozillacert96.pem | 2014 年 3 月 13 日 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| mozillacert142.pem | 2014 年 3 月 13 日 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| mozillacert34.pem | 2014 年 3 月 13 日 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| mozillacert1.pem | 2014 年 3 月 13 日 | 23:E5:94:94:51:95:F2:41:48:03:B4:D5:64:D2:A3:A3:F5:D8:8B:8C | 
| mozillacert85.pem | 2014 年 3 月 13 日 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| mozillacert131.pem | 2014 年 3 月 13 日 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| mozillacert149.pem | 2014 年 3 月 13 日 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| mozillacert23.pem | 2014 年 3 月 13 日 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| mozillacert8.pem | 2014 年 3 月 13 日 | 3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F | 
| mozillacert74.pem | 2014 年 3 月 13 日 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| mozillacert120.pem | 2014 年 3 月 13 日 | DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41 | 
| mozillacert138.pem | 2014 年 3 月 13 日 | E1:9F:E3:0E:8B:84:60:9E:80:9B:17:0D:72:A8:C5:BA:6E:14:09:BD | 
| mozillacert12.pem | 2014 年 3 月 13 日 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| mozillacert63.pem | 2014 年 3 月 13 日 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| mozillacert127.pem | 2014 年 3 月 13 日 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| mozillacert19.pem | 2014 年 3 月 13 日 | B4:35:D4:E1:11:9D:1C:66:90:A7:49:EB:B3:94:BD:63:7B:A7:82:B7 | 
| mozillacert52.pem | 2014 年 3 月 13 日 | 8B:AF:4C:9B:1D:F0:2A:92:F7:DA:12:8E:B9:1B:AC:F4:98:60:4B:6F | 
| mozillacert116.pem | 2014 年 3 月 13 日 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| mozillacert41.pem | 2014 年 3 月 13 日 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| mozillacert59.pem | 2014 年 3 月 13 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| mozillacert105.pem | 2014 年 3 月 13 日 | 77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC | 
| mozillacert92.pem | 2014 年 3 月 13 日 | A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0 | 
| mozillacert30.pem | 2014 年 3 月 13 日 | E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE | 
| mozillacert48.pem | 2014 年 3 月 13 日 | A0:A1:AB:90:C9:FC:84:7B:3B:12:61:E8:97:7D:5F:D3:22:61:D3:CC | 
| verisignc4g2.pem | 2014 年 3 月 20 日 | 0B:77:BE:BB:CB:7A:A2:47:05:DE:CC:0F:BD:6A:02:FC:7A:BD:9B:52 | 
| verisignc2g3.pem | 2014 年 3 月 20 日 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| verisignc1g6.pem | 2014 年 12 月 31 日 | 51:7F:61:1E:29:91:6B:53:82:FB:72:E7:44:D9:8D:C3:CC:53:6D:64 | 
| verisignc2g2.pem | 2014 年 3 月 20 日 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| verisignroot.pem | 2014 年 3 月 20 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| verisignc2g1.pem | 2014 年 3 月 20 日 | 67:82:AA:E0:ED:EE:E2:1A:58:39:D3:C0:CD:14:68:0A:4F:60:14:2A | 
| verisignc3g5.pem | 2014 年 3 月 20 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| verisignc1g3.pem | 2014 年 3 月 20 日 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| verisignc3g4.pem | 2014 年 3 月 20 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignc1g2.pem | 2014 年 3 月 20 日 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| verisignc3g3.pem | 2014 年 3 月 20 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| verisignc1g1.pem | 2014 年 3 月 20 日 | 90:AE:A2:69:85:FF:14:80:4C:43:49:52:EC:E9:60:84:77:AF:55:6F | 
| verisignc3g2.pem | 2014 年 3 月 20 日 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| verisignc3g1.pem | 2014 年 3 月 20 日 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| verisignc2g6.pem | 2014 年 12 月 31 日 | 40:B3:31:A0:E9:BF:E8:55:BC:39:93:CA:70:4F:4E:C2:51:D4:1D:8F | 
| verisignc4g3.pem | 2014 年 3 月 20 日 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| gdroot-g2.pem | 2014 年 12 月 31 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| gd-class2-root.pem | 2014 年 12 月 31 日 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| gd\$1bundle-g2.pem | 2014 年 12 月 31 日 | 27:AC:93:69:FA:F2:52:07:BB:26:27:CE:FA:CC:BE:4E:F9:C3:19:B8 | 
| dstacescax6 | 2018 年 6 月 18 日 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| gd\$1bundle-g2.pem | 2018 年 6 月 18 日 | 27:AC:93:69:FA:F2:52:07:BB:26:27:CE:FA:CC:BE:4E:F9:C3:19:B8 | 
| verisignc4g3.pem | 2018 年 6 月 18 日 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| swisssignplatinumg2ca | 2018 年 4 月 21 日 | 56:E0:FA:C0:3B:8F:18:23:55:18:E5:D3:11:CA:E8:C2:43:31:AB:66 | 
| geotrustprimarycertificationauthorityg3 | 2018 年 6 月 18 日 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| geotrustprimarycertificationauthorityg2 | 2018 年 6 月 18 日 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| buypassclass2rootca | 2018 年 6 月 18 日 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| camerfirmachambersofcommerceroot | 2018 年 6 月 18 日 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| mozillacert20.pem | 2018 年 6 月 18 日 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert12.pem | 2018 年 6 月 18 日 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| mozillacert90.pem | 2018 年 6 月 18 日 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| mozillacert82.pem | 2018 年 6 月 18 日 | 2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3 | 
| mozillacert140.pem | 2018 年 6 月 18 日 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| mozillacert74.pem | 2018 年 6 月 18 日 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| mozillacert132.pem | 2018 年 6 月 18 日 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| mozillacert66.pem | 2018 年 6 月 18 日 | DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34 | 
| mozillacert124.pem | 2018 年 6 月 18 日 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| mozillacert58.pem | 2018 年 6 月 18 日 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| securitycommunicationrootca2 | 2018 年 6 月 18 日 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| mozillacert116.pem | 2018 年 6 月 18 日 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| mozillacert108.pem | 2018 年 6 月 18 日 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| certigna | 2018 年 6 月 18 日 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| mozillacert3.pem | 2018 年 6 月 18 日 | 87:9F:4B:EE:05:DF:98:58:3B:E3:60:D6:33:E7:0D:3F:FE:98:71:AF | 
| verisignc1g1.pem | 2018 年 6 月 18 日 | 90:AE:A2:69:85:FF:14:80:4C:43:49:52:EC:E9:60:84:77:AF:55:6F | 
| verisignc4g2.pem | 2018 年 6 月 18 日 | 0B:77:BE:BB:CB:7A:A2:47:05:DE:CC:0F:BD:6A:02:FC:7A:BD:9B:52 | 
| deutschetelekomrootca2 | 2018 年 6 月 18 日 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| starfieldrootg2ca | 2018 年 4 月 21 日 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| comodoecccertificationauthority | 2018 年 6 月 18 日 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| digicertglobalrootg3 | 2018 年 6 月 18 日 | 7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E | 
| digicertglobalrootg2 | 2018 年 6 月 18 日 | DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4 | 
| mozillacert11.pem | 2018 年 6 月 18 日 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| mozillacert81.pem | 2018 年 6 月 18 日 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| mozillacert73.pem | 2018 年 6 月 18 日 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| szafirrootca2 | 2018 年 6 月 18 日 | E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE | 
| mozillacert131.pem | 2018 年 6 月 18 日 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| ecacc | 2018 年 6 月 18 日 | 28:90:3A:63:5B:52:80:FA:E6:77:4C:0B:6D:A7:D6:BA:A6:4A:F2:E8 | 
| mozillacert65.pem | 2018 年 6 月 18 日 | 69:BD:8C:F4:9C:D3:00:FB:59:2E:17:93:CA:55:6A:F3:EC:AA:35:FB | 
| turktrustelektroniksertifikahizmetsaglayicisih5 | 2018 年 6 月 18 日 | C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB | 
| mozillacert123.pem | 2018 年 6 月 18 日 | 2A:B6:28:48:5E:78:FB:F3:AD:9E:79:10:DD:6B:DF:99:72:2C:96:E5 | 
| mozillacert57.pem | 2018 年 6 月 18 日 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| mozillacert115.pem | 2018 年 6 月 18 日 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| mozillacert49.pem | 2018 年 6 月 18 日 | 61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71 | 
| mozillacert107.pem | 2018 年 6 月 18 日 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| verisignclass3g4ca | 2018 年 4 月 21 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| securetrustca | 2018 年 6 月 18 日 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| mozillacert2.pem | 2018 年 6 月 18 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| buypassclass2ca | 2018 年 4 月 21 日 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| secomscrootca2 | 2018 年 4 月 21 日 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| secomscrootca1 | 2018 年 4 月 21 日 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| trustisfpsrootca | 2018 年 6 月 18 日 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| hongkongpostrootca1 | 2018 年 6 月 18 日 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| certsignrootca | 2018 年 6 月 18 日 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| geotrustprimaryca | 2018 年 4 月 21 日 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| twcaglobalrootca | 2018 年 6 月 18 日 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| camerfirmachambersca | 2018 年 4 月 21 日 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| mozillacert10.pem | 2018 年 6 月 18 日 | 5F:3A:FC:0A:8B:64:F6:86:67:34:74:DF:7E:A9:A2:FE:F9:FA:7A:51 | 
| mozillacert80.pem | 2018 年 6 月 18 日 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| mozillacert72.pem | 2018 年 6 月 18 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| comodoaaaca | 2018 年 4 月 21 日 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert130.pem | 2018 年 6 月 18 日 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| mozillacert64.pem | 2018 年 6 月 18 日 | 62:7F:8D:78:27:65:63:99:D2:7D:7F:90:44:C9:FE:B3:F3:3E:FA:9A | 
| mozillacert122.pem | 2018 年 6 月 18 日 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| mozillacert56.pem | 2018 年 6 月 18 日 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| equifaxsecureebusinessca1 | 2018 年 4 月 21 日 | AE:E6:3D:70:E3:76:FB:C7:3A:EB:B0:A1:C1:D4:C4:7A:A7:40:B3:F4 | 
| camerfirmachambersignca | 2018 年 4 月 21 日 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| mozillacert114.pem | 2018 年 6 月 18 日 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| mozillacert48.pem | 2018 年 6 月 18 日 | A0:A1:AB:90:C9:FC:84:7B:3B:12:61:E8:97:7D:5F:D3:22:61:D3:CC | 
| pscprocert | 2018 年 6 月 18 日 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| mozillacert106.pem | 2018 年 6 月 18 日 | E7:A1:90:29:D3:D5:52:DC:0D:0F:C6:92:D3:EA:88:0D:15:2E:1A:6B | 
| mozillacert1.pem | 2018 年 6 月 18 日 | 23:E5:94:94:51:95:F2:41:48:03:B4:D5:64:D2:A3:A3:F5:D8:8B:8C | 
| eecertificationcentrerootca | 2018 年 6 月 18 日 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| digicertglobalrootca | 2018 年 6 月 18 日 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| thawteprimaryrootcag3 | 2018 年 6 月 18 日 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| thawteprimaryrootcag2 | 2018 年 6 月 18 日 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| entrustrootcertificationauthorityec1 | 2018 年 6 月 18 日 | 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 | 
| valicertclass2ca | 2018 年 4 月 21 日 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| globalchambersignroot2008 | 2018 年 6 月 18 日 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| amazonrootca4 | 2018 年 6 月 18 日 | F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE | 
| gd-class2-root.pem | 2018 年 6 月 18 日 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| amazonrootca3 | 2018 年 6 月 18 日 | 0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E | 
| amazonrootca2 | 2018 年 6 月 18 日 | 5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A | 
| securitycommunicationrootca | 2018 年 6 月 18 日 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| amazonrootca1 | 2018 年 6 月 18 日 | 8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16 | 
| acraizfnmtrcm | 2018 年 6 月 18 日 | EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20 | 
| quovadisrootca3g3 | 2018 年 6 月 18 日 | 48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D | 
| certplusrootcag2 | 2018 年 6 月 18 日 | 4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A | 
| certplusrootcag1 | 2018 年 6 月 18 日 | 22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66 | 
| mozillacert71.pem | 2018 年 6 月 18 日 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| mozillacert63.pem | 2018 年 6 月 18 日 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| mozillacert121.pem | 2018 年 6 月 18 日 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| ttelesecglobalrootclass3ca | 2018 年 4 月 21 日 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| mozillacert55.pem | 2018 年 6 月 18 日 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| mozillacert113.pem | 2018 年 6 月 18 日 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| baltimorecybertrustca | 2018 年 4 月 21 日 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| mozillacert47.pem | 2018 年 6 月 18 日 | 1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96 | 
| mozillacert105.pem | 2018 年 6 月 18 日 | 77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC | 
| mozillacert39.pem | 2018 年 6 月 18 日 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| usertrustecccertificationauthority | 2018 年 6 月 18 日 | D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0 | 
| mozillacert0.pem | 2018 年 6 月 18 日 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| securitycommunicationevrootca1 | 2018 年 6 月 18 日 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| verisignc3g5.pem | 2018 年 6 月 18 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| globalsignr3ca | 2018 年 4 月 21 日 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| trustcoreca1 | 2018 年 6 月 18 日 | 58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD | 
| equifaxsecureglobalebusinessca1 | 2018 年 4 月 21 日 | 3A:74:CB:7A:47:DB:70:DE:89:1F:24:35:98:64:B8:2D:82:BD:1A:36 | 
| geotrustuniversalca | 2018 年 6 月 18 日 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| affirmtrustpremiumca | 2018 年 4 月 21 日 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| staatdernederlandenrootcag3 | 2018 年 6 月 18 日 | D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC | 
| staatdernederlandenrootcag2 | 2018 年 6 月 18 日 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| mozillacert70.pem | 2018 年 6 月 18 日 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| secomevrootca1 | 2018 年 4 月 21 日 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| geotrustglobalca | 2018 年 6 月 18 日 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| mozillacert62.pem | 2018 年 6 月 18 日 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| mozillacert120.pem | 2018 年 6 月 18 日 | DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41 | 
| mozillacert54.pem | 2018 年 6 月 18 日 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| mozillacert112.pem | 2018 年 6 月 18 日 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| mozillacert46.pem | 2018 年 6 月 18 日 | 40:9D:4B:D9:17:B5:5C:27:B6:9B:64:CB:98:22:44:0D:CD:09:B8:89 | 
| swisssigngoldcag2 | 2018 年 6 月 18 日 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert104.pem | 2018 年 6 月 18 日 | 4F:99:AA:93:FB:2B:D1:37:26:A1:99:4A:CE:7F:F0:05:F2:93:5D:1E | 
| mozillacert38.pem | 2018 年 6 月 18 日 | CB:A1:C5:F8:B0:E3:5E:B8:B9:45:12:D3:F9:34:A2:E9:06:10:D3:36 | 
| certplusclass3pprimaryca | 2018 年 4 月 21 日 | 21:6B:2A:29:E6:2A:00:CE:82:01:46:D8:24:41:41:B9:25:11:B2:79 | 
| entrustrootcertificationauthorityg2 | 2018 年 6 月 18 日 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| godaddyrootg2ca | 2018 年 4 月 21 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| cfcaevroot | 2018 年 6 月 18 日 | E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 | 
| verisignc3g4.pem | 2018 年 6 月 18 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| geotrustuniversalca2 | 2018 年 6 月 18 日 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| starfieldservicesrootg2ca | 2018 年 4 月 21 日 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| digicerthighassuranceevrootca | 2018 年 6 月 18 日 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| entrustnetpremium2048secureserverca | 2018 年 6 月 18 日 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| camerfirmaglobalchambersignroot | 2018 年 6 月 18 日 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| verisignclass3g3ca | 2018 年 4 月 21 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| godaddyclass2ca | 2018 年 6 月 18 日 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| mozillacert61.pem | 2018 年 6 月 18 日 | E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84 | 
| mozillacert53.pem | 2018 年 6 月 18 日 | 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74 | 
| atostrustedroot2011 | 2018 年 6 月 18 日 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| mozillacert111.pem | 2018 年 6 月 18 日 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| staatdernederlandenevrootca | 2018 年 6 月 18 日 | 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB | 
| mozillacert45.pem | 2018 年 6 月 18 日 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert103.pem | 2018 年 6 月 18 日 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| mozillacert37.pem | 2018 年 6 月 18 日 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| mozillacert29.pem | 2018 年 6 月 18 日 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| izenpecom | 2018 年 6 月 18 日 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| comodorsacertificationauthority | 2018 年 6 月 18 日 | AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4 | 
| mozillacert99.pem | 2018 年 6 月 18 日 | F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33 | 
| mozillacert149.pem | 2018 年 6 月 18 日 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| utnuserfirstobjectca | 2018 年 4 月 21 日 | E1:2D:FB:4B:41:D7:D9:C3:2B:30:51:4B:AC:1D:81:D8:38:5E:2D:46 | 
| verisignc3g3.pem | 2018 年 6 月 18 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| dstrootcax3 | 2018 年 6 月 18 日 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| addtrustexternalroot | 2018 年 6 月 18 日 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| certumtrustednetworkca | 2018 年 6 月 18 日 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| affirmtrustpremiumecc | 2018 年 6 月 18 日 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| starfieldclass2ca | 2018 年 6 月 18 日 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| actalisauthenticationrootca | 2018 年 6 月 18 日 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| verisignclass2g3ca | 2018 年 4 月 21 日 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| isrgrootx1 | 2018 年 6 月 18 日 | CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8 | 
| godaddyrootcertificateauthorityg2 | 2018 年 6 月 18 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| mozillacert60.pem | 2018 年 6 月 18 日 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| chunghwaepkirootca | 2018 年 4 月 21 日 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert52.pem | 2018 年 6 月 18 日 | 8B:AF:4C:9B:1D:F0:2A:92:F7:DA:12:8E:B9:1B:AC:F4:98:60:4B:6F | 
| microseceszignorootca2009 | 2018 年 6 月 18 日 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| securesignrootca11 | 2018 年 6 月 18 日 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| mozillacert110.pem | 2018 年 6 月 18 日 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| mozillacert44.pem | 2018 年 6 月 18 日 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| mozillacert102.pem | 2018 年 6 月 18 日 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| mozillacert36.pem | 2018 年 6 月 18 日 | 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D | 
| mozillacert28.pem | 2018 年 6 月 18 日 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| baltimorecybertrustroot | 2018 年 6 月 18 日 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| amzninternalrootca | 2008 年 12 月 12 日 | A7:B7:F6:15:8A:FF:1E:C8:85:13:38:BC:93:EB:A2:AB:A4:09:EF:06 | 
| mozillacert98.pem | 2018 年 6 月 18 日 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| mozillacert148.pem | 2018 年 6 月 18 日 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| verisignc3g2.pem | 2018 年 6 月 18 日 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| quovadisrootca2g3 | 2018 年 6 月 18 日 | 09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36 | 
| geotrustprimarycertificationauthority | 2018 年 6 月 18 日 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| opentrustrootcag3 | 2018 年 6 月 18 日 | 6E:26:64:F3:56:BF:34:55:BF:D1:93:3F:7C:01:DE:D8:13:DA:8A:A6 | 
| opentrustrootcag2 | 2018 年 6 月 18 日 | 79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B | 
| opentrustrootcag1 | 2018 年 6 月 18 日 | 79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E | 
| verisignclass3ca | 2018 年 4 月 21 日 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| globalsignca | 2018 年 4 月 21 日 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| ttelesecglobalrootclass2ca | 2018 年 4 月 21 日 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| verisignclass1g3ca | 2018 年 4 月 21 日 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| verisignuniversalrootca | 2018 年 4 月 21 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| soneraclass2ca | 2018 年 4 月 21 日 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| starfieldservicesrootcertificateauthorityg2 | 2018 年 6 月 18 日 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| mozillacert51.pem | 2018 年 6 月 18 日 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| mozillacert43.pem | 2018 年 6 月 18 日 | F9:CD:0E:2C:DA:76:24:C1:8F:BD:F0:F0:AB:B6:45:B8:F7:FE:D5:7A | 
| mozillacert101.pem | 2018 年 6 月 18 日 | 99:A6:9B:E6:1A:FE:88:6B:4D:2B:82:00:7C:B8:54:FC:31:7E:15:39 | 
| mozillacert35.pem | 2018 年 6 月 18 日 | 2A:C8:D5:8B:57:CE:BF:2F:49:AF:F2:FC:76:8F:51:14:62:90:7A:41 | 
| globalsignr2ca | 2018 年 4 月 21 日 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| mozillacert27.pem | 2018 年 6 月 18 日 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| affirmtrustpremium | 2018 年 6 月 18 日 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| mozillacert19.pem | 2018 年 6 月 18 日 | B4:35:D4:E1:11:9D:1C:66:90:A7:49:EB:B3:94:BD:63:7B:A7:82:B7 | 
| mozillacert97.pem | 2018 年 6 月 18 日 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| netlockaranyclassgoldfotanusitvany | 2018 年 6 月 18 日 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| mozillacert89.pem | 2018 年 6 月 18 日 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| verisignroot.pem | 2018 年 6 月 18 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| mozillacert147.pem | 2018 年 6 月 18 日 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| aolrootca2 | 2018 年 4 月 21 日 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| cia-crt-g3-01-ca | 2016 年 11 月 23 日 | 2B:EE:2C:BA:A3:1D:B5:FE:60:40:41:95:08:ED:46:82:39:4D:ED:E2 | 
| aolrootca1 | 2018 年 4 月 21 日 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| verisignc3g1.pem | 2018 年 6 月 18 日 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| mozillacert139.pem | 2018 年 6 月 18 日 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| soneraclass2rootca | 2018 年 6 月 18 日 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| swisssignsilverg2ca | 2018 年 4 月 21 日 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| thawteprimaryrootca | 2018 年 6 月 18 日 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| gdcatrustauthr5root | 2018 年 6 月 18 日 | 0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4 | 
| trustcenterclass4caii | 2018 年 4 月 21 日 | A6:9A:91:FD:05:7F:13:6A:42:63:0B:B1:76:0D:2D:51:12:0C:16:50 | 
| usertrustrsacertificationauthority | 2018 年 6 月 18 日 | 2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E | 
| digicertassuredidrootg3 | 2018 年 6 月 18 日 | F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89 | 
| digicertassuredidrootg2 | 2018 年 6 月 18 日 | A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F | 
| mozillacert50.pem | 2018 年 6 月 18 日 | 8C:96:BA:EB:DD:2B:07:07:48:EE:30:32:66:A0:F3:98:6E:7C:AE:58 | 
| mozillacert42.pem | 2018 年 6 月 18 日 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| mozillacert100.pem | 2018 年 6 月 18 日 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| mozillacert34.pem | 2018 年 6 月 18 日 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| affirmtrustcommercialca | 2018 年 4 月 21 日 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| mozillacert26.pem | 2018 年 6 月 18 日 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| globalsigneccrootcar5 | 2018 年 6 月 18 日 | 1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA | 
| globalsigneccrootcar4 | 2018 年 6 月 18 日 | 69:69:56:2E:40:80:F4:24:A1:E7:19:9F:14:BA:F3:EE:58:AB:6A:BB | 
| buypassclass3rootca | 2018 年 6 月 18 日 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| mozillacert18.pem | 2018 年 6 月 18 日 | 79:98:A3:08:E1:4D:65:85:E6:C2:1E:15:3A:71:9F:BA:5A:D3:4A:D9 | 
| mozillacert96.pem | 2018 年 6 月 18 日 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| verisignc2g6.pem | 2018 年 6 月 18 日 | 40:B3:31:A0:E9:BF:E8:55:BC:39:93:CA:70:4F:4E:C2:51:D4:1D:8F | 
| secomvalicertclass1ca | 2018 年 4 月 21 日 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| mozillacert88.pem | 2018 年 6 月 18 日 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| accvraiz1 | 2018 年 6 月 18 日 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| mozillacert146.pem | 2018 年 6 月 18 日 | 21:FC:BD:8E:7F:6C:AF:05:1B:D1:B3:43:EC:A8:E7:61:47:F2:0F:8A | 
| mozillacert138.pem | 2018 年 6 月 18 日 | E1:9F:E3:0E:8B:84:60:9E:80:9B:17:0D:72:A8:C5:BA:6E:14:09:BD | 
| verisignclass3g2ca | 2018 年 4 月 21 日 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| dtrustrootclass3ca2ev2009 | 2018 年 6 月 18 日 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| xrampglobalca | 2018 年 4 月 21 日 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| mozillacert9.pem | 2018 年 6 月 18 日 | F4:8B:11:BF:DE:AB:BE:94:54:20:71:E6:41:DE:6B:BE:88:2B:40:B9 | 
| verisignuniversalrootcertificationauthority | 2018 年 6 月 18 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| tubitakkamusmsslkoksertifikasisurum1 | 2018 年 6 月 18 日 | 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA | 
| mozillacert41.pem | 2018 年 6 月 18 日 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| mozillacert33.pem | 2018 年 6 月 18 日 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| mozillacert25.pem | 2018 年 6 月 18 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| mozillacert17.pem | 2018 年 6 月 18 日 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| mozillacert95.pem | 2018 年 6 月 18 日 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| affirmtrustpremiumeccca | 2018 年 4 月 21 日 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| mozillacert87.pem | 2018 年 6 月 18 日 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| mozillacert145.pem | 2018 年 6 月 18 日 | 10:1D:FA:3F:D5:0B:CB:BB:9B:B5:60:0C:19:55:A4:1A:F4:73:3A:04 | 
| mozillacert79.pem | 2018 年 6 月 18 日 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| mozillacert137.pem | 2018 年 6 月 18 日 | 4A:65:D5:F4:1D:EF:39:B8:B8:90:4A:4A:D3:64:81:33:CF:C7:A1:D1 | 
| digicertassuredidrootca | 2018 年 6 月 18 日 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| addtrustqualifiedca | 2018 年 4 月 21 日 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| mozillacert129.pem | 2018 年 6 月 18 日 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| verisignclass2g2ca | 2018 年 4 月 21 日 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| baltimorecodesigningca | 2018 年 4 月 21 日 | 30:46:D8:C8:88:FF:69:30:C3:4A:FC:CD:49:27:08:7C:60:56:7B:0D | 
| luxtrustglobalroot2 | 2018 年 6 月 18 日 | 1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F | 
| visaecommerceroot | 2018 年 6 月 18 日 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| oistewisekeyglobalrootgbca | 2018 年 6 月 18 日 | 0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED | 
| mozillacert8.pem | 2018 年 6 月 18 日 | 3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F | 
| comodocertificationauthority | 2018 年 6 月 18 日 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| cia-crt-g3-02-ca | 2016 年 11 月 23 日 | 96:4A:BB:A7:BD:DA:FC:97:34:C0:0A:2D:F0:05:98:F7:E6:C6:6F:09 | 
| verisignc1g6.pem | 2018 年 6 月 18 日 | 51:7F:61:1E:29:91:6B:53:82:FB:72:E7:44:D9:8D:C3:CC:53:6D:64 | 
| trustcenterclass2caii | 2018 年 4 月 21 日 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| quovadisrootca1g3 | 2018 年 6 月 18 日 | 1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67 | 
| mozillacert40.pem | 2018 年 6 月 18 日 | 80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5 | 
| cadisigrootr2 | 2018 年 6 月 18 日 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| cadisigrootr1 | 2018 年 6 月 18 日 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| mozillacert32.pem | 2018 年 6 月 18 日 | 60:D6:89:74:B5:C2:65:9E:8A:0F:C1:88:7C:88:D2:46:69:1B:18:2C | 
| utndatacorpsgcca | 2018 年 4 月 21 日 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| mozillacert24.pem | 2018 年 6 月 18 日 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| addtrustclass1ca | 2018 年 4 月 21 日 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| mozillacert16.pem | 2018 年 6 月 18 日 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| affirmtrustnetworkingca | 2018 年 4 月 21 日 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| mozillacert94.pem | 2018 年 6 月 18 日 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| mozillacert86.pem | 2018 年 6 月 18 日 | 74:2C:31:92:E6:07:E4:24:EB:45:49:54:2B:E1:BB:C5:3E:61:74:E2 | 
| mozillacert144.pem | 2018 年 6 月 18 日 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| mozillacert78.pem | 2018 年 6 月 18 日 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| mozillacert136.pem | 2018 年 6 月 18 日 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert128.pem | 2018 年 6 月 18 日 | A9:E9:78:08:14:37:58:88:F2:05:19:B0:6D:2B:0D:2B:60:16:90:7D | 
| verisignclass1g2ca | 2018 年 4 月 21 日 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| hellenicacademicandresearchinstitutionsrootca2015 | 2018 年 6 月 18 日 | 01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6 | 
| soneraclass1ca | 2018 年 4 月 21 日 | 07:47:22:01:99:CE:74:B9:7C:B0:3D:79:B2:64:A2:C8:55:E9:33:FF | 
| hellenicacademicandresearchinstitutionsrootca2011 | 2018 年 6 月 18 日 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| certumtrustednetworkca2 | 2018 年 6 月 18 日 | D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92 | 
| equifaxsecureca | 2018 年 4 月 21 日 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| thawteserverca | 2018 年 4 月 21 日 | 9F:AD:91:A6:CE:6A:C6:C5:00:47:C4:4E:C9:D4:A5:0D:92:D8:49:79 | 
| mozillacert7.pem | 2018 年 6 月 18 日 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| affirmtrustnetworking | 2018 年 6 月 18 日 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| deprecateditsecca | 2012 年 1 月 27 日 | 12:12:0B:03:0E:15:14:54:F4:DD:B3:F5:DE:13:6E:83:5A:29:72:9D | 
| globalsignrootcar3 | 2018 年 6 月 18 日 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| globalsignrootcar2 | 2018 年 6 月 18 日 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| quovadisrootca | 2018 年 6 月 18 日 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| mozillacert31.pem | 2018 年 6 月 18 日 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| entrustrootcertificationauthority | 2018 年 6 月 18 日 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert23.pem | 2018 年 6 月 18 日 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| mozillacert15.pem | 2018 年 6 月 18 日 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| verisignc2g3.pem | 2018 年 6 月 18 日 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| mozillacert93.pem | 2018 年 6 月 18 日 | 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17 | 
| mozillacert151.pem | 2018 年 6 月 18 日 | AC:ED:5F:65:53:FD:25:CE:01:5F:1F:7A:48:3B:6A:74:9F:61:78:C6 | 
| mozillacert85.pem | 2018 年 6 月 18 日 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| certplusclass2primaryca | 2018 年 6 月 18 日 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| mozillacert143.pem | 2018 年 6 月 18 日 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| mozillacert77.pem | 2018 年 6 月 18 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| mozillacert135.pem | 2018 年 6 月 18 日 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| mozillacert69.pem | 2018 年 6 月 18 日 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| mozillacert127.pem | 2018 年 6 月 18 日 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| mozillacert119.pem | 2018 年 6 月 18 日 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| geotrustprimarycag3 | 2018 年 4 月 21 日 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| identrustpublicsectorrootca1 | 2018 年 6 月 18 日 | BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD | 
| geotrustprimarycag2 | 2018 年 4 月 21 日 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| trustcorrootcertca2 | 2018 年 6 月 18 日 | B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0 | 
| mozillacert6.pem | 2018 年 6 月 18 日 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| trustcorrootcertca1 | 2018 年 6 月 18 日 | FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A | 
| networksolutionscertificateauthority | 2018 年 6 月 18 日 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| twcarootcertificationauthority | 2018 年 6 月 18 日 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| addtrustexternalca | 2018 年 4 月 21 日 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| verisignclass3g5ca | 2018 年 4 月 21 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| autoridaddecertificacionfirmaprofesionalcifa62634068 | 2018 年 6 月 18 日 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| hellenicacademicandresearchinstitutionseccrootca2015 | 2018 年 6 月 18 日 | 9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66 | 
| verisigntsaca | 2018 年 4 月 21 日 | 20:CE:B1:F0:F5:1C:0E:19:A9:F3:8D:B1:AA:8E:03:8C:AA:7A:C7:01 | 
| utnuserfirsthardwareca | 2018 年 4 月 21 日 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| identrustcommercialrootca1 | 2018 年 6 月 18 日 | DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 | 
| dtrustrootclass3ca22009 | 2018 年 6 月 18 日 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| epkirootcertificationauthority | 2018 年 6 月 18 日 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert30.pem | 2018 年 6 月 18 日 | E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE | 
| teliasonerarootcav1 | 2018 年 6 月 18 日 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| buypassclass3ca | 2018 年 4 月 21 日 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| mozillacert22.pem | 2018 年 6 月 18 日 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| mozillacert14.pem | 2018 年 6 月 18 日 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| verisignc2g2.pem | 2018 年 6 月 18 日 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| certumca | 2018 年 4 月 21 日 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| mozillacert92.pem | 2018 年 6 月 18 日 | A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0 | 
| mozillacert150.pem | 2018 年 6 月 18 日 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| mozillacert84.pem | 2018 年 6 月 18 日 | D3:C0:63:F2:19:ED:07:3E:34:AD:5D:75:0B:32:76:29:FF:D5:9A:F2 | 
| ttelesecglobalrootclass3 | 2018 年 6 月 18 日 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| globalsignrootca | 2018 年 6 月 18 日 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| ttelesecglobalrootclass2 | 2018 年 6 月 18 日 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| mozillacert142.pem | 2018 年 6 月 18 日 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| mozillacert76.pem | 2018 年 6 月 18 日 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| mozillacert134.pem | 2018 年 6 月 18 日 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| mozillacert68.pem | 2018 年 6 月 18 日 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| etugracertificationauthority | 2018 年 6 月 18 日 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| mozillacert126.pem | 2018 年 6 月 18 日 | 25:01:90:19:CF:FB:D9:99:1C:B7:68:25:74:8D:94:5F:30:93:95:42 | 
| keynectisrootca | 2018 年 4 月 21 日 | 9C:61:5C:4D:4D:85:10:3A:53:26:C2:4D:BA:EA:E4:A2:D2:D5:CC:97 | 
| mozillacert118.pem | 2018 年 6 月 18 日 | 7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45 | 
| quovadisrootca3 | 2018 年 6 月 18 日 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| quovadisrootca2 | 2018 年 6 月 18 日 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| mozillacert5.pem | 2018 年 6 月 18 日 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| verisignc1g3.pem | 2018 年 6 月 18 日 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| cybertrustglobalroot | 2018 年 6 月 18 日 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| amzninternalinfoseccag3 | 2015 年 2 月 27 日 | B9:B1:CA:38:F7:BF:9C:D2:D4:95:E7:B6:5E:75:32:9B:A8:78:2E:F6 | 
| starfieldrootcertificateauthorityg2 | 2018 年 6 月 18 日 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| entrust2048ca | 2018 年 4 月 21 日 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| swisssignsilvercag2 | 2018 年 6 月 18 日 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| affirmtrustcommercial | 2018 年 6 月 18 日 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| certinomisrootca | 2018 年 6 月 18 日 | 9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8 | 
| xrampglobalcaroot | 2018 年 6 月 18 日 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| secureglobalca | 2018 年 6 月 18 日 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| swisssigngoldg2ca | 2018 年 4 月 21 日 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert21.pem | 2018 年 6 月 18 日 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| mozillacert13.pem | 2018 年 6 月 18 日 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| verisignc2g1.pem | 2018 年 6 月 18 日 | 67:82:AA:E0:ED:EE:E2:1A:58:39:D3:C0:CD:14:68:0A:4F:60:14:2A | 
| mozillacert91.pem | 2018 年 6 月 18 日 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| oistewisekeyglobalrootgaca | 2018 年 6 月 18 日 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| mozillacert83.pem | 2018 年 6 月 18 日 | A0:73:E5:C5:BD:43:61:0D:86:4C:21:13:0A:85:58:57:CC:9C:EA:46 | 
| entrustevca | 2018 年 4 月 21 日 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert141.pem | 2018 年 6 月 18 日 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| mozillacert75.pem | 2018 年 6 月 18 日 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| mozillacert133.pem | 2018 年 6 月 18 日 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| mozillacert67.pem | 2018 年 6 月 18 日 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| mozillacert125.pem | 2018 年 6 月 18 日 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert59.pem | 2018 年 6 月 18 日 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| thawtepremiumserverca | 2018 年 4 月 21 日 | E0:AB:05:94:20:72:54:93:05:60:62:02:36:70:F7:CD:2E:FC:66:66 | 
| mozillacert117.pem | 2018 年 6 月 18 日 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| utnuserfirstclientauthemailca | 2018 年 4 月 21 日 | B1:72:B1:A5:6D:95:F9:1F:E5:02:87:E1:4D:37:EA:6A:44:63:76:8A | 
| entrustrootcag2 | 2018 年 4 月 21 日 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| mozillacert109.pem | 2018 年 6 月 18 日 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| digicerttrustedrootg4 | 2018 年 6 月 18 日 | DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4 | 
| gdroot-g2.pem | 2018 年 6 月 18 日 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| comodoaaaservicesroot | 2018 年 6 月 18 日 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert4.pem | 2018 年 6 月 18 日 | E3:92:51:2F:0A:CF:F5:05:DF:F6:DE:06:7F:75:37:E1:65:EA:57:4B | 
| verisignclass3publicprimarycertificationauthorityg5 | 2018 年 6 月 18 日 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| chambersofcommerceroot2008 | 2018 年 6 月 18 日 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| verisignclass3publicprimarycertificationauthorityg4 | 2018 年 6 月 18 日 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignclass3publicprimarycertificationauthorityg3 | 2018 年 6 月 18 日 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| thawtepersonalfreemailca | 2018 年 4 月 21 日 | E6:18:83:AE:84:CA:C1:C1:CD:52:AD:E8:E9:25:2B:45:A6:4F:B7:E2 | 
| verisignc1g2.pem | 2018 年 6 月 18 日 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| gtecybertrustglobalca | 2018 年 4 月 21 日 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| trustcenteruniversalcai | 2018 年 4 月 21 日 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| camerfirmachamberscommerceca | 2018 年 4 月 21 日 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| verisignclass1ca | 2018 年 4 月 21 日 | CE:6A:64:A3:09:E4:2F:BB:D9:85:1C:45:3E:64:09:EA:E8:7D:60:F1 | 

# AWS AppSync 解析器映射模板更新日志
<a name="resolver-mapping-template-changelog"></a>

**注意**  
我们现在主要支持 APPSYNC\$1JS 运行时系统及其文档。请考虑使用 APPSYNC\$1JS 运行时系统和[此处](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)的指南。

解析器和函数映射模板已版本化。映射模板版本（例如 `2018-05-29`）指示以下内容：
+ 请求模板提供的数据来源请求配置的预期形状
+ 请求映射模板和响应映射模板的执行行为

版本使用 YYYY-MM-DD格式表示，较晚的日期对应于较新的版本。该页面列出了 AWS AppSync中当前支持的映射模板版本之间的差异。

**Topics**
+ [每个版本矩阵的数据来源操作可用性](#aws-appsync-resolver-mapping-template-operation-availability-per-version)
+ [更改单位解析器映射模板上的版本](#changing-the-version-on-a-unit-resolver-mapping-template)
+ [更改函数上的版本](#changing-the-version-on-a-function)
+ [2018-05-29](#aws-appsync-resolver-mapping-template-version-2018-05-29)
+ [2017-02-28](#aws-appsync-resolver-mapping-template-version-2017-02-28)

## 每个版本矩阵的数据来源操作可用性
<a name="aws-appsync-resolver-mapping-template-operation-availability-per-version"></a>


| 支持的操作/版本 | 2017-02-28 | 2018-05-29 | 
| --- | --- | --- | 
|  AWS Lambda 调用  |  支持  |  是  | 
|  AWS Lambda BatchInvoke  |  是  |  是  | 
|  None Datasource  |  支持  |  是  | 
|  Amazon OpenSearch GET  |  支持  |  是  | 
|  Amazon OpenSearch POST  |  支持  |  是  | 
|  亚马逊 P OpenSearch UT  |  支持  |  是  | 
|  亚马逊 OpenSearch 删除  |  支持  |  是  | 
|  Amazon OpenSearch GET  |  支持  |  是  | 
|  DynamoDB GetItem  |  支持  |  是  | 
|  DynamoDB Scan  |  支持  |  是  | 
|  DynamoDB Query  |  支持  |  是  | 
|  DynamoDB DeleteItem  |  支持  |  是  | 
|  DynamoDB PutItem  |  支持  |  是  | 
|  DynamoDB BatchGetItem  |  否  |  是  | 
|  DynamoDB BatchPutItem  |  否  |  是  | 
|  DynamoDB BatchDeleteItem  |  否  |  是  | 
|  HTTP  |  否  |  是  | 
|  Amazon RDS  |  否  |  是  | 

 **注**：函数中目前仅支持 **2018-05-29** 版本。

## 更改单位解析器映射模板上的版本
<a name="changing-the-version-on-a-unit-resolver-mapping-template"></a>

对于单位解析器，将版本指定为请求映射模板正文的一部分。要更新版本，只需将 `version` 字段更新为新版本。

例如，要更新 AWS Lambda 模板上的版本，请执行以下操作：

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "arguments": $utils.toJson($context.arguments)
    }
}
```

您需要将版本字段从 `2017-02-28` 更新为 `2018-05-29`，如下所示：

```
{
    "version": "2018-05-29", ## Note the version
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "arguments": $utils.toJson($context.arguments)
    }
}
```

## 更改函数上的版本
<a name="changing-the-version-on-a-function"></a>

对于函数，将版本指定为函数对象上的 `functionVersion` 字段。要更新版本，只需更新 `functionVersion`。*注意：*目前，函数仅支持 `2018-05-29`。

以下是用于更新现有函数版本的 CLI 命令的示例：

```
aws appsync update-function \
--api-id REPLACE_WITH_API_ID \
--function-id REPLACE_WITH_FUNCTION_ID \
--data-source-name "PostTable" \
--function-version "2018-05-29" \
--request-mapping-template "{...}" \
--response-mapping-template "\$util.toJson(\$ctx.result)"
```

 **注意：**建议从函数请求映射模板中省略版本字段，因为它不会被接受。如果您在函数请求映射模板中指定了一个版本，则该版本值将由 `functionVersion` 字段的值覆盖。

## 2018-05-29
<a name="aws-appsync-resolver-mapping-template-version-2018-05-29"></a>

### 行为更改
<a name="behavior-change"></a>
+ 如果数据来源调用结果为 `null`，则执行响应映射模板。
+ 如果数据来源调用产生了错误，现在由您来处理该错误，响应映射模板评估结果将**始终**放置在 GraphQL 响应 `data` 块中。

### Reasoning
<a name="reasoning"></a>
+ `null` 调用结果具有意义，在某些应用程序使用案例中，我们可能希望以自定义方式处理 `null` 结果。例如，应用程序可能会检查 Amazon DynamoDB 表中是否存在记录以执行某些授权检查。在这种情况下，`null` 调用结果意味着用户可能未获得授权。现在，执行响应映射模板可以引发未经授权的错误。此行为向 API 设计器提供了更大的控制。

给定以下响应映射模板：

```
$util.toJson($ctx.result)
```

之前使用 `2017-02-28`，如果 `$ctx.result` 返回 null，则未执行响应映射模板。利用 `2018-05-29`，我们现在可以处理这种情况。例如，我们可以选择引发授权错误，如下所示：

```
# throw an unauthorized error if the result is null
#if ( $util.isNull($ctx.result) )
    $util.unauthorized()
#end
$util.toJson($ctx.result)
```

 **注：**从数据来源返回的错误有时并不是致命的，或者甚至是预期的，这就是应向响应映射模板提供处理调用错误并决定是否忽略它、重新引发它或引发不同的错误的灵活性。

给定以下响应映射模板：

```
$util.toJson($ctx.result)
```

以前，使用 `2017-02-28`，如果出现调用错误，则会评估响应映射模板，并自动将结果放入 GraphQL 响应的 `errors` 块中。利用 `2018-05-29`，我们现在可以选择如何处理错误，重新引发错误、引发不同的错误，或者在返回数据时追加错误。

### 重新引发调用错误
<a name="re-raise-an-invocation-error"></a>

在以下响应模板中，我们引发了从数据来源返回的同一错误。

```
#if ( $ctx.error )
    $util.error($ctx.error.message, $ctx.error.type)
#end
$util.toJson($ctx.result)
```

如果出现调用错误（例如，出现 `$ctx.error`），则响应如下所示：

```
{
    "data": {
        "getPost": null
    },
    "errors": [
        {
            "path": [
                "getPost"
            ],
            "errorType": "DynamoDB:ConditionalCheckFailedException",
            "message": "Conditional check failed exception...",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ]
        }
    ]
}
```

### 引发不同的错误
<a name="raise-a-different-error"></a>

在以下响应模板中，我们在处理从数据来源返回的错误之后引发了自己的自定义错误。

```
#if ( $ctx.error )
    #if ( $ctx.error.type.equals("ConditionalCheckFailedException") )
        ## we choose here to change the type and message of the error for ConditionalCheckFailedExceptions
        $util.error("Error while updating the post, try again. Error: $ctx.error.message", "UpdateError")
    #else
        $util.error($ctx.error.message, $ctx.error.type)
    #end
#end
$util.toJson($ctx.result)
```

如果出现调用错误（例如，出现 `$ctx.error`），则响应如下所示：

```
{
    "data": {
        "getPost": null
    },
    "errors": [
        {
            "path": [
                "getPost"
            ],
            "errorType": "UpdateError",
            "message": "Error while updating the post, try again. Error: Conditional check failed exception...",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ]
        }
    ]
}
```

### 追加错误以返回数据
<a name="append-an-error-to-return-data"></a>

在以下响应模板中，我们追加从数据来源返回的同一错误，同时将数据返回到响应中。这也称为部分响应。

```
#if ( $ctx.error )
    $util.appendError($ctx.error.message, $ctx.error.type)
    #set($defaultPost = {id: "1", title: 'default post'})
    $util.toJson($defaultPost)
#else
    $util.toJson($ctx.result)
#end
```

如果出现调用错误（例如，出现 `$ctx.error`），则响应如下所示：

```
{
    "data": {
        "getPost": {
            "id": "1",
            "title: "A post"
        }
    },
    "errors": [
        {
            "path": [
                "getPost"
            ],
            "errorType": "ConditionalCheckFailedException",
            "message": "Conditional check failed exception...",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ]
        }
    ]
}
```

#### 从 *2017-02-28* 迁移到 *2018-05-29*
<a name="migrating-from-2017-02-28-to-2018-05-29"></a>

从 **2017-02-28** 迁移到 **2018-05-29** 非常简单。更改解析器请求映射模板或函数版本对象上的版本字段。但请注意，**2018-05-29** 执行的行为与 **2017-02-28** 的不同，[此处](#aws-appsync-resolver-mapping-template-version-2018-05-29)概述了更改。

#### 从 *2017-02-28* 到 *2018-05-29* 保留相同的执行行为
<a name="preserving-the-same-execution-behavior-from-2017-02-28-to-2018-05-29"></a>

在某些情况下，在执行 **2018-05-29** 版本的模板时，可以保留与 **2017-02-28** 版本相同的执行行为。

### 示例：DynamoDB PutItem
<a name="example-dynamodb-putitem"></a>

鉴于以下 **2017-02-28** DynamoDB 请求模板 PutItem：

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "attributeValues" : {
        "baz" : ... typed value
    },
    "condition" : {
       ...
    }
}
```

以及以下响应模板：

```
$util.toJson($ctx.result)
```

迁移到 **2018-05-29** 会更改这些模板，如下所示：

```
{
    "version" : "2018-05-29", ## Note the new 2018-05-29 version
    "operation" : "PutItem",
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "attributeValues" : {
        "baz" : ... typed value
    },
    "condition" : {
       ...
    }
}
```

更改响应模板，如下所示：

```
## If there is a datasource invocation error, we choose to raise the same error
## the field data will be set to null.
#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
#end

## If the data source invocation is null, we return null.
#if($util.isNull($ctx.result))
  #return
#end

$util.toJson($ctx.result)
```

现在，您有责任处理错误，我们选择使用从 DynamoDB 返回的 `$util.error()` 来引发同一错误。您可以调整此代码段以将映射模板转换为 **2018-05-29**，请注意，如果您的响应模板不同，则必须考虑执行行为更改。

### 示例：DynamoDB GetItem
<a name="example-dynamodb-getitem"></a>

鉴于以下 **2017-02-28** DynamoDB 请求模板 GetItem：

```
{
    "version" : "2017-02-28",
    "operation" : "GetItem",
    "key" : {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "consistentRead" : true
}
```

以及以下响应模板：

```
## map table attribute postId to field Post.id
$util.qr($ctx.result.put("id", $ctx.result.get("postId")))

$util.toJson($ctx.result)
```

迁移到 **2018-05-29** 会更改这些模板，如下所示：

```
{
    "version" : "2018-05-29", ## Note the new 2018-05-29 version
    "operation" : "GetItem",
    "key" : {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "consistentRead" : true
}
```

更改响应模板，如下所示：

```
## If there is a datasource invocation error, we choose to raise the same error
#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type)
#end

## If the data source invocation is null, we return null.
#if($util.isNull($ctx.result))
  #return
#end

## map table attribute postId to field Post.id
$util.qr($ctx.result.put("id", $ctx.result.get("postId")))

$util.toJson($ctx.result)
```

在 **2017-02-28** 版本中，如果数据来源调用是 `null`，则表示 DynamoDB 表中没有与我们的键匹配的项目，响应映射模板将不会执行。在大多数情况下，这都是可行的，但如果您期望 `$ctx.result` 不是 `null`，则现在必须处理该情况。

## 2017-02-28
<a name="aws-appsync-resolver-mapping-template-version-2017-02-28"></a>

### 特性
<a name="characteristics"></a>
+ 如果数据来源调用结果为 `null`，则**不会**执行响应映射模板。
+ 如果数据来源调用产生了错误，则将执行响应映射模板，并将评估结果放入 GraphQL 响应 `errors.data` 块中。