

# 在 API Gateway 中设置采用有效载荷响应流式传输的 Lambda 代理集成
<a name="response-transfer-mode-lambda"></a>

您可以流式传输 Lambda 函数的响应，以缩短首字节时间（TTFB），并在部分响应可用时立即将其发送给客户端。API Gateway 要求您使用 [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html) Lambda API 来调用 Lambda 函数。API Gateway 会向 Lambda 函数传递一个事件对象。后端 Lambda 函数会对传入请求数据进行解析，以确定要返回的响应。为了让 API Gateway 能够流式传输 Lambda 输出，Lambda 函数必须按照 API Gateway 要求的[格式](#response-transfer-mode-lambda-format)输出。

## 流和缓冲响应传输模式下 Lambda 代理集成的差异
<a name="response-transfer-mode-lambda-comparison"></a>

以下列表描述了 Lambda 代理集成与用于响应流式传输的 Lambda 代理集成之间的差异：
+ API Gateway 使用 [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html) API 调用用于响应流式处理的 Lambda 代理集成。这会生成不同的 URI，具体如下所示：

  ```
  arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations
  ```

  与 Lambda 代理集成相比，此 ARN 对 API 版本使用不同的日期和不同的服务操作。

  如果您使用 API Gateway 控制台进行响应流式传输，则控制台会自动为您使用正确的 URI。
+ 在 Lambda 代理集成中，API Gateway 仅在收到 Lambda 的完整响应后才会将响应发送给客户端。在用于响应流式传输的 Lambda 代理集成中，API Gateway 在收到 Lambda 的有效元数据和分隔符后即开始有效载荷流式传输。
+ 用于响应流式传输的 Lambda 代理集成使用与普通代理集成相同的输入格式，但要求不同的输出格式。

## 用于响应流式传输的 Lambda 代理集成格式
<a name="response-transfer-mode-lambda-format"></a>

当 API Gateway 调用具有响应流式传输功能的 Lambda 函数时，输入格式与代理集成的 Lambda 函数输入格式相同。有关更多信息，请参阅 [用于代理集成的 Lambda 函数的输入格式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format)。

当 Lambda 向 API Gateway 流式传输响应时，响应必须遵循以下格式。该格式使用分隔符分隔元数据 JSON 和原始有效载荷。在这种情况下，有效载荷数据会按照流式 Lambda 函数传输的方式进行流式传输：

```
{
  "headers": {"headerName": "headerValue", ...},
  "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
  "cookies" : ["cookie1", "cookie2"],
  "statusCode": httpStatusCode
}<DELIMITER>PAYLOAD1 | PAYLOAD2 | PAYLOAD3
```

在输出中：
+ 如果不返回任何额外的响应标头，则可以不指定 `headers`、`multiValueHeaders`、`cookies` 和 `statusCode` 键。
+ `headers` 密钥只能包含单值标头。
+ 输出要求标头中包含 `Transfer-Encoding: chunked` 或 `Content-length: number`。如果您的函数未返回这两个标头中的任何一个，API Gateway 会在响应标头中添加 `Transfer-Encoding: chunked`。
+ `multiValueHeaders` 密钥可以包含多值标头以及单值标头。您可以使用 `multiValueHeaders` 密钥来指定所有额外的标头，包括任何单值标头。
+ 如果您指定 `headers` 和 `multiValueHeaders` 的值，API Gateway 会将它们合并为一个列表。如果两者都指定了相同的键/值对，则合并列表中只会出现 `multiValueHeaders` 的值。
+ 元数据必须是有效的 JSON 格式。仅支持 `headers`、`multiValueHeaders`、`cookies` 和 `statusCode` 键。
+ 必须在元数据 JSON 后面提供一个分隔符。该分隔符必须是 8 个空字节，且必须出现在流数据的前 16 KB 内。
+ API Gateway 对方法响应有效载荷没有特定格式要求。

如果您使用函数 URL 流式传输 Lambda 函数，必须修改 Lambda 函数的输入和输出以满足这些要求。

如果您的 Lambda 函数输出不符合此格式要求，API Gateway 仍可能调用您的 Lambda 函数，但会返回错误。下表展示了 API Gateway 支持的 API 集成请求设置与 Lambda 函数代码的组合。这包括响应传输模式为缓冲时支持的组合。


| 响应传输模式 | 函数代码符合要求的格式 | Lambda 调用 API | API Gateway 是否支持 | 
| --- | --- | --- | --- | 
|  流  |  是  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  可以。API Gateway 流式传输您的响应。  | 
|  流  |  否  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  否。API Gateway 调用您的 Lambda 函数并返回 500 错误响应。  | 
|  流  |  是  |   [调用](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  否。API Gateway 不支持此集成配置。  | 
|  流  |  否  |   [调用](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  否。API Gateway 不支持此集成配置。  | 
|  缓冲  |  是  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  否。API Gateway 不支持此集成配置。  | 
|  缓冲  |  否  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  否。API Gateway 不支持此集成配置。  | 
|  缓冲  |  是  |   [调用](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  API Gateway 返回 HTTP 标头和状态码，但不返回响应正文。  | 
|  缓冲  |  否  |   [调用](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  可以。这是 Lambda 代理集成。有关更多信息，请参阅 [Lambda 代理集成](set-up-lambda-proxy-integrations.md)。  | 