【问题标题】:Trouble with API Gateway to Lambda using CDK使用 CDK 到 Lambda 的 API 网关出现问题
【发布时间】:2021-10-01 18:12:30
【问题描述】:

我正在使用 Python CDK 部署由 API 调用触发的 Lambda 函数。这是我的代码:

app.py

#!/usr/bin/env python3
import os

from aws_cdk import core

from cvsg_app_bff.usermanagement import UserManagementStack

app = core.App()
UserManagementStack(app, "UserManagementStack")

app.synth()

我的堆栈:

class UserManagementStack(core.Stack):

def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Lambda functions
    create_new_user: _lambda.Function = _lambda.Function(self, "newUserLambdaHandler",
                                                            runtime=_lambda.Runtime.PYTHON_3_8,
                                                            handler="usermanagement.create_new_user",
                                                            code=_lambda.Code.from_asset("lambda_functions")
                                                            )

    # API gateway setup
    user_apis = api_gw.LambdaRestApi(self, 'UserManagementAPIs', handler=create_new_user, proxy=False)

    user_apis.root.resource_for_path('user').add_method('POST', api_gw.LambdaIntegration(create_new_user))

包含 Lambda 函数的文件:

def format_return(status_code, response_body):
    response = {
        'statusCode': status_code,
        'body': response_body
    }
    print("Response: ", str(response))
    return response


def is_admin(event):
    # todo: not implemented yet!
    return True


def get_event_body(event):
    print(json.dumps(event))
    return json.loads(event["body"])


def create_new_user(event, context):
    request_body = get_event_body(event)
    if is_admin(event):
        return format_return(200, request_body)
    else:
        return format_return(403, "Not Unauthorised for this operation")

当我部署并点击端点时,我收到一条带有此消息的 502 Bad Gateway 响应

{
    "message": "Internal server error"
}

我查看了 CloudWatch 日志,可以看到在 format_response 方法中打印的正确响应,但来自客户端的响应始终是 502。

如何让 API 网关返回正确的响应?

【问题讨论】:

  • 您的 Lambda 函数返回的最终值是多少?
  • create_new_user 是 lambda 处理程序。函数的返回值就是 lambda 应该返回的值。

标签: amazon-web-services aws-lambda aws-api-gateway aws-cdk


【解决方案1】:

您的问题似乎是您的 Lambda 函数返回了不正确的响应。 API Gateway 通过 Lambda Proxy Integrations 调用的 Lambda 函数需要返回一个 JSON 对象,格式如下:

{
    "isBase64Encoded": True|False,
    "statusCode": <status code>,
    "headers": {
        "header-name": "header-value",
        # ...
    },
    "body": "{\"your\":\"data\"}" # <--- MUST be a string, NOT an object
}

您的create_new_user 函数返回format_return(200, request_body),其中request_bodyget_event_body 的结果,它返回json.loads(返回一个dict,不是字符串)。

像这样更改get_event_body 应该可以解决问题:

def get_event_body(event):
    print(json.dumps(event))
    return json.dumps(event["body"])

【讨论】:

  • 不使用代理集成。如果 lambda 不是作为代理的设置,它应该返回什么。来自我的代码user_apis = api_gw.LambdaRestApi(self, 'UserManagementAPIs', handler=create_new_user, proxy=False)
  • 其实你是。见here“使用 AWS Lambda 代理集成定义 API Gateway REST API。”
  • 您的主要问题是您返回一个 Python 对象(即dict)作为您的body 而不是str。几周前,我在自己的项目中为此挠了好几个小时。
  • 哦,我明白了,您指定了proxy=False。无论哪种方式,我相信 Lambda 函数需要返回相同的主体。
  • 我昨天本来是想回复的,但是忘记了。除了接受它之外,考虑支持我的答案...... :)
猜你喜欢
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 2020-12-08
  • 2021-07-02
  • 2018-08-27
  • 2017-09-19
  • 1970-01-01
相关资源
最近更新 更多