

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

# 扩展程序
<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"
        }
      })
  ```