

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

# Amazon Pip EventBridge es 输入转换
<a name="eb-pipes-input-transformation"></a>

Amazon Pip EventBridge es 在向浓缩和目标传递数据时支持可选的输入转换器。您可以使用输入转换器来重塑 JSON 事件输入负载，以满足富集或目标服务的需求。对于 Amazon API Gateway 和 API 目的地，您可以通过这种方式根据您的 API RESTful 模型调整输入事件。输入转换器作为 `InputTemplate` 参数建模。它们可以是自由文本、事件负载的 JSON 路径或包含事件负载内联 JSON 路径的 JSON 对象。对于富集，事件负载来自源。对于目标，如果在管道中配置了富集，则事件负载是从富集中返回的内容。除了事件负载中的服务特定数据外，您还可以使用 `InputTemplate` 中的[保留变量](#input-transform-reserved)来引用管道的数据。

要访问数组中的项目，请使用方括号表示法。

**注意**  
EventBridge 不支持所有 JSON Path 语法并在运行时对其进行评估。支持的语法包括：  
点表示法（例如 `$.detail`）
短划线
下划线
字母数字字符
数组索引
通配符 (\$1)
向前斜杠

以下是引用 Amazon SQS 事件负载的示例 `InputTemplate` 参数：

**静态字符串**

```
InputTemplate: "Hello, sender"
```

**JSON 路径**

```
InputTemplate: <$.attributes.SenderId>
```

**动态字符串**

```
InputTemplate: "Hello, <$.attributes.SenderId>"
```

**静态 JSON**

```
InputTemplate: >
{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
}
```

**动态 JSON**

```
InputTemplate: >
{
  "key1": "value1"
  "key2": <$.body.key>,
  "d": <aws.pipes.event.ingestion-time>
}
```

使用方括号表示法访问数组中的项目。

```
InputTemplate: >
{
  "key1": "value1"
  "key2": <$.body.Records[3]>,
  "d": <aws.pipes.event.ingestion-time>
}
```

**注意**  
EventBridge 在运行时替换输入转换器以确保有效的 JSON 输出。因此，请在引用 JSON 路径参数的变量前后加引号，但不要在引用 JSON 对象或数组的变量前后加引号。

## 预留变量
<a name="input-transform-reserved"></a>

输入模板可以使用以下预留变量：
+ `<aws.pipes.pipe-arn>` - 管道的 Amazon 资源名称 (ARN)。
+ `<aws.pipes.pipe-name>` - 管道的名称。
+ `<aws.pipes.source-arn>` - 管道事件源的 ARN。
+ `<aws.pipes.enrichment-arn>` - 管道富集的 ARN。
+ `<aws.pipes.target-arn>` - 管道目标的 ARN。
+ `<aws.pipes.event.ingestion-time>` - 输入转换器收到事件的时间。这是 ISO 8601 时间戳。这个时间对于富集输入转换器和目标输入转换器来说是不同的，具体取决于富集完成事件处理的时间。
+ `<aws.pipes.event>` - 输入转换器接收到的事件。

  对于富集输入转换器，这是来自源的事件。它包含来自源的原始负载，以及其他特定于服务的元数据。如需特定于此服务的示例，请参阅 [Amazon Pi EventBridge pes 来源](eb-pipes-event-source.md)中的主题。

  对于目标输入转换器，这是由富集返回的事件（如果已配置富集），不包含其他元数据。因此，富集返回的负载可能是非 JSON。如果未在管道中配置富集，则这是来自源的事件，包含元数据。
+ `<aws.pipes.event.json>` - 与`aws.pipes.event` 相同，但是只有当原始负载（来自源或由富集返回）为 JSON 时，该变量才有值。如果管道有编码字段，例如 Amazon SQS `body` 字段或 Kinesis `data`，则会对这些字段进行解码，并转换为有效的 JSON。由于该变量未被转义，因此只能用作 JSON 字段的值。有关更多信息，请参阅 [隐式正文数据解析](#input-transform-implicit)。

## 输入转换示例
<a name="input-transform-example"></a>

以下是 Amazon EC2 事件的示例，我们可以将其用作*示例事件*。

```
{
  "version": "0",
  "id": "7bf73129-1428-4cd3-a780-95db273d1602",
  "detail-type": "EC2 Instance State-change Notification",
  "source": "aws.ec2",
  "account": "123456789012",
  "time": "2015-11-11T21:29:54Z",
  "region": "us-east-1",
  "resources": [
    "arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"
  ],
  "detail": {
    "instance-id": "i-0123456789",
    "state": "RUNNING"
  }
}
```

让我们使用以下 JSON 作为*转换器*。

```
{
  "instance" : <$.detail.instance-id>,
  "state": <$.detail.state>,
  "pipeArn" : <aws.pipes.pipe-arn>,
  "pipeName" : <aws.pipes.pipe-name>,
  "originalEvent" : <aws.pipes.event.json>
}
```

以下是生成的*输出*：

```
{
  "instance" : "i-0123456789",
  "state": "RUNNING",
  "pipeArn" : "arn:aws:pipe:us-east-1:123456789012:pipe/example",
  "pipeName" : "example",
  "originalEvent" : {
    ... // commented for brevity
  }
}
```

## 隐式正文数据解析
<a name="input-transform-implicit"></a>

传入负载中的以下字段可能是 JSON 转义的（例如 Amazon SQS `body` 对象），也可能是 base64 编码的，例如 Kinesis `data` 对象。对于[筛选](eb-pipes-event-filtering.md)和输入转换，将这些字段 EventBridge 转换为有效的 JSON，以便可以直接引用子值。例如，适用于 Kinesis 的 `<$.data.someKey>`。

要让目标接收原始负载（不包含任何其他元数据），请针对特定于源的正文数据使用输入转换器。例如，适用于 Amazon SQS 的 `<$.body>` 或适用于 Kinesis 的 `<$.data>`。如果原始负载是有效的 JSON 字符串（例如 `{"key": "value"}`），则针对特定于源的正文数据使用输入转换器，将导致原始源负载中的引号被删除。例如，在传送到目标时，`{"key": "value"}` 会变成 `"{key: value}"`。如果您的目标需要有效的 JSON 有效负载（例如 Lamb EventBridge da 或 Step Functions），这将导致交付失败。要让目标接收原始源数据而不生成无效 JSON，请将源正文数据输入转换器包装在 JSON 中。例如 `{"data": <$.data>}`。

隐式正文解析还可用于动态填充大多数管道目标或富集参数的值。有关更多信息，请参阅 [动态路径参数](eb-pipes-event-target.md#pipes-targets-dynamic-parms)。

**注意**  
如果原始负载是有效的 JSON，此字段将包含未转义、非 base64 编码的 JSON。但是，如果有效负载不是有效的 JSON，则会对下面列出的字段进行 EventBridge base64 编码，但亚马逊 SQS 除外。
+ **Active MQ** - `data`
+ **Kinesis** - `data`
+ **Amazon MSK** - `key` 和 `value`
+ **Rabbit MQ** - `data`
+ **自托管 Apache Kafka** - `key` 和 `value`
+ **Amazon SQS** - `body`

## 转换输入的常见问题
<a name="eb-pipes-transform-input-issues"></a>

以下是在 EventBridge 管道中转换输入时的一些常见问题：
+  对于字符串，需要引号。
+  为模板创建 JSON 路径时不进行验证。
+  如果您指定一个变量，匹配在事件中不存在的 JSON 路径，则不会创建该变量，并且不会在输出中显示该变量。
+ 像 `aws.pipes.event.json` 这样的 JSON 属性只能用作 JSON 字段的值，不能在其他字符串中内联。
+  EventBridge 填充目标的*输入*模板时，不会转义输入*路径*提取的值。
+ 如果 JSON 路径引用了 JSON 对象或数组，但变量是在字符串中引用的，则 EventBridge 删除所有内部引号以确保字符串有效。例如，“正文为 <\$1.body>” 将导致从对象中 EventBridge 删除引号。

  因此，如果要根据单个 JSON 路径变量输出 JSON 对象，则必须将其作为键。在本示例中，`{"body": <$.body>}`。
+ 表示字符串的变量不需要引号。允许使用它们，但是 Pip EventBridge es 会在转换过程中自动为字符串变量值添加引号，以确保转换输出是有效的 JSON。 EventBridge 管道不会为表示 JSON 对象或数组的变量添加引号。不要为表示 JSON 对象或数组的变量添加引号。

  例如，以下输入模板包含的变量表示字符串和 JSON 对象：

  ```
  {
    "pipeArn" : <aws.pipes.pipe-arn>,
    "pipeName" : <aws.pipes.pipe-name>,
    "originalEvent" : <aws.pipes.event.json>
  }
  ```

  生成带有正确引号的有效 JSON：

  ```
  {
    "pipeArn" : "arn:aws:events:us-east-2:123456789012:pipe/example",
    "pipeName" : "example",
    "originalEvent" : {
      ... // commented for brevity
    }
  }
  ```
+ 对于 Lambda 或 Step Functions 富集或目标，即使批次大小为 1，批次也会作为 JSON 数组传送到目标。但是，输入转换器仍将应用于 JSON 数组中的单个记录，而不是整个数组。有关更多信息，请参阅 [Amazon Pip EventBridge es 批处理和并发](eb-pipes-batching-concurrency.md)。
+ 输入转换器和过滤可以提取经过一次字符串编码的 JSON 值，但不能提取经过两次字符串编码的值。这种情况通常发生在向亚马逊 SQS 发送亚马逊 SNS 消息时。当 Amazon SQS 收到亚马逊 SNS 消息时，它会对整条消息进行字符串化。然后，当 Pipes 收到这条 Amazon SQS 消息时，Amazon SNS 消息内容将出现在字段中并且`body`可以访问。但是，如果 Amazon SNS `Message` 字段本身包含字符串化的 JSON，则该嵌套内容将采用双重编码，无法通过输入转换器或筛选器进行访问。例如，可以访问`<$.body.TopicArn>`，但如果`Message`字段包含字符串化`<$.body.Message.operation>`的 JSON，则不可访问，`"{\\\"operation\\\":\\\"UPDATE\\\",\\\"email\\\":\\\"user@example.com\\\"}"`例如。

  要解决此限制，请使用带有 Lambda 函数的丰富步骤来解析双重编码的内容并提取嵌套值。有关扩充的更多信息，请参阅[富集](pipes-enrichment.md)。