

# 针对 API Gateway 中的 HTTP API 创建 AWS Lambda 代理集成
<a name="http-api-develop-integrations-lambda"></a>

通过 Lambda 代理集成，您可以将 API 路由与 Lambda 函数集成。当客户端调用您的 API 时，API Gateway 将请求发送到 Lambda 函数并将该函数的响应返回给客户端。有关创建 HTTP API 的示例，请参阅 [创建 HTTP API](http-api-develop.md#http-api-examples)。

## 负载格式版本
<a name="http-api-develop-integrations-lambda.proxy-format"></a>

负载格式版本指定 API Gateway 发送到 Lambda 集成的事件的格式，以及 API Gateway 如何解释来自 Lambda 的响应。如果未指定负载格式版本，则默认情况下 AWS 管理控制台 使用最新版本。如果您通过使用 AWS CLI、CloudFormation 或开发工具包创建 Lambda 集成，则必须指定 `payloadFormatVersion`。支持的值是 `1.0` 和 `2.0`。

有关如何设置 `payloadFormatVersion` 的更多信息，请参阅 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html)。有关如何确定现有集成的 `payloadFormatVersion` 的更多信息，请参阅 [get-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/get-integration.html)。

### 负载格式差异
<a name="http-api-develop-integrations-lambda.proxy-format-differences"></a>

以下列表显示了 `1.0` 和 `2.0` 负载格式版本之间的差异：
+ 格式 `2.0` 没有 `multiValueHeaders` 或 `multiValueQueryStringParameters` 字段。重复的标头使用逗号组合，包含在 `headers` 字段中。重复的查询字符串使用逗号组合，包含在 `queryStringParameters` 字段中。
+ 格式 `2.0` 具有 `rawPath`。如果您使用 API 映射将阶段连接到自定义域名，`rawPath` 不会提供 API 映射值。使用格式 `1.0` 和 `path` 可访问自定义域名的 API 映射。
+ 格式 `2.0` 包含一个新 `cookies` 字段。请求中的所有 Cookie 标头均使用逗号组合并添加到 `cookies` 字段中。在对客户端的响应中，每个 Cookie 都成为一个 `set-cookie` 标头。

### 负载格式结构
<a name="http-api-develop-integrations-lambda.proxy-format-structure"></a>

以下示例显示了每个负载格式版本的结构。所有标头名称均为小写。

------
#### [ 2.0 ]

```
{
  "version": "2.0",
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": [
    "cookie1",
    "cookie2"
  ],
  "headers": {
    "header1": "value1",
    "header2": "value1,value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "api-id",
    "authentication": {
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "authorizer": {
      "jwt": {
        "claims": {
          "claim1": "value1",
          "claim2": "value2"
        },
        "scopes": [
          "scope1",
          "scope2"
        ]
      }
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "192.0.2.1",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "body": "Hello from Lambda",
  "pathParameters": {
    "parameter1": "value1"
  },
  "isBase64Encoded": false,
  "stageVariables": {
    "stageVariable1": "value1",
    "stageVariable2": "value2"
  }
}
```

------
#### [ 1.0 ]

```
{
  "version": "1.0",
  "resource": "/my/path",
  "path": "/my/path",
  "httpMethod": "GET",
  "headers": {
    "header1": "value1",
    "header2": "value2"
  },
  "multiValueHeaders": {
    "header1": [
      "value1"
    ],
    "header2": [
      "value1",
      "value2"
    ]
  },
  "queryStringParameters": {
    "parameter1": "value1",
    "parameter2": "value"
  },
  "multiValueQueryStringParameters": {
    "parameter1": [
      "value1",
      "value2"
    ],
    "parameter2": [
      "value"
    ]
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "id",
    "authorizer": {
      "claims": null,
      "scopes": null
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "extendedRequestId": "request-id",
    "httpMethod": "GET",
    "identity": {
      "accessKey": null,
      "accountId": null,
      "caller": null,
      "cognitoAuthenticationProvider": null,
      "cognitoAuthenticationType": null,
      "cognitoIdentityId": null,
      "cognitoIdentityPoolId": null,
      "principalOrgId": null,
      "sourceIp": "192.0.2.1",
      "user": null,
      "userAgent": "user-agent",
      "userArn": null,
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "path": "/my/path",
    "protocol": "HTTP/1.1",
    "requestId": "id=",
    "requestTime": "04/Mar/2020:19:15:17 +0000",
    "requestTimeEpoch": 1583349317135,
    "resourceId": null,
    "resourcePath": "/my/path",
    "stage": "$default"
  },
  "pathParameters": null,
  "stageVariables": null,
  "body": "Hello from Lambda!",
  "isBase64Encoded": false
}
```

------

## Lambda 函数响应格式
<a name="http-api-develop-integrations-lambda.response"></a>

负载格式版本确定 Lambda 函数必须返回的响应结构。

### 格式 1.0 的 Lambda 函数响应
<a name="http-api-develop-integrations-lambda.v1"></a>

对于 `1.0` 格式版本，Lambda 集成必须返回采用以下 JSON 格式的响应：

**Example**  

```
{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headername": "headervalue", ... },
    "multiValueHeaders": { "headername": ["headervalue", "headervalue2", ...], ... },
    "body": "..."
}
```

### 格式 2.0 的 Lambda 函数响应
<a name="http-api-develop-integrations-lambda.v2"></a>

使用 `2.0` 格式版本，API Gateway 可以推断您的响应格式。如果您的 Lambda 函数返回有效的 JSON 并且没有返回 `statusCode`，API Gateway 会做出以下假设：
+ `isBase64Encoded` 为 `false`。
+ `statusCode` 为 `200`。
+ `content-type` 为 `application/json`。
+ `body` 是函数的响应。

以下示例显示 Lambda 函数的输出和 API Gateway 的解释。


| Lambda 函数输出 | API Gateway 解释 | 
| --- | --- | 
|  <pre>"Hello from Lambda!"</pre>  |  <pre>{<br />  "isBase64Encoded": false,<br />  "statusCode": 200,<br />  "body": "Hello from Lambda!",<br />  "headers": {<br />    "content-type": "application/json"<br />  }<br />}</pre>  | 
|  <pre>{ "message": "Hello from Lambda!" }</pre>  |  <pre>{<br />  "isBase64Encoded": false,<br />  "statusCode": 200,<br />  "body": "{ \"message\": \"Hello from Lambda!\" }",<br />  "headers": {<br />    "content-type": "application/json"<br />  }<br />}</pre>  | 

要自定义响应，您的 Lambda 函数应返回以下格式的响应。

```
{
    "cookies" : ["cookie1", "cookie2"],
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headername": "headervalue", ... },
    "body": "Hello from Lambda!"
}
```