在AWS里,可以将API Gateway HTTP 的某个route接到某个Lambda函数上,gateway接收到请求的时候,会调用Lambda函数,再将结果返回给gateway,gateway返回给客户端。那当Lambda收到API Gateway的请求的时候,函数收到的参数是什么呢?

1. gateway传给Lambda的格式

apigateway 调用lambda时会有一个固定的json格式

参考Aws里的文档Create integrations for HTTP APIs in API Gateway

收到Payload 有两种格式,可配置用哪个。 现在有1.0和2.0。

Lmabda收到的就是一整个的json,从里面可以获取到请求参数,请求体

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
}

2. lambda 返回函数格式

也会有两种返回的格式。

  • 1.0 的必须要按照指定的格式返回,就是字段要和结构一致

    Lambda function response for format 1.0 . With the 1.0 format version, Lambda integrations must return a response in the following JSON format…

  • 2.0的API Gateway 会自己推断 自己推断的意思是你可以直接返回一个json,例如用户信息的json,API Gateway会再自己转换为固定的格式。 会按照下面的格式,最后返回给客户端的就是状态码200这些。 isBase64Encoded:false. • statusCode is 200. • content-type is application/json. • body is the function’s response

另外一种是如果你想设置自定义的请求头,可以就需要返回他的格式,他的格式里可以指定自定义的请求头和状态码,还有body。

Lambda function response for format 2.0 With the 2.0 format version, API Gateway can infer the response format for you. API Gateway makes the following assumptions if your Lambda function returns valid JSON and doesn’t return astatusCode:

isBase64Encoded的意思是,如果为true,gateway会对body这个string进行base64解码成byte数组再返回给客户端。 因为lambda返回的要是json字符串,所以如果包含二进制的话,需要进行base64编码成base64编码后的字符串再设置isBase64=true。 例如有个修改的需求是需要对Lambda的响应内容进行gzip编码,就需要对gzip后得到的数组在lambda base encode后设置到body再返回。

示例

使用Java sdk开发时,aws已经提供了输入,输出的类型类,可以直接使用,类的结构就是对应payload 2.0的格式。


import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse;

public class XXHandler implements RequestHandler<APIGatewayV2HTTPEvent, APIGatewayV2HTTPResponse> {