如何修改AWS Lambda代码,使其兼容控制台与Function URL调用?
问题根源
当通过Function URL或API Gateway调用Lambda时,输入并非直接是你定义的FramerInput对象,而是一个包含HTTP请求元数据(请求体、头部、路径等)的事件对象(如APIGatewayProxyRequest或APIGatewayHttpApiV2ProxyRequest)。原代码仅处理了直接调用(控制台/VS Toolkit)时的FramerInput输入,因此HTTP调用时会将整个事件对象反序列化为FramerInput,导致inner和outer字段为空,最终返回空的framed值。
修改方案
要让Lambda同时支持两种调用模式,需完成以下操作:
步骤1:安装依赖NuGet包
在Visual Studio的NuGet包管理器中安装Amazon.Lambda.APIGatewayEvents,该包包含HTTP触发所需的事件和响应类型定义。
步骤2:修改Lambda代码
using Amazon.Lambda.Core; using Amazon.Lambda.RuntimeSupport; using Amazon.Lambda.Serialization.SystemTextJson; using Amazon.Lambda.APIGatewayEvents; using System.Text.Json; var handler = (object input, ILambdaContext context) => { FramerInput framerInput; object response; // 处理控制台/VS Toolkit直接调用的情况 if (input is FramerInput directInput) { framerInput = directInput; response = new FramerOutput { framed = $"{framerInput.outer}{framerInput.inner}{framerInput.outer}" }; } // 处理API Gateway V1格式的HTTP请求 else if (input is APIGatewayProxyRequest httpRequest) { framerInput = JsonSerializer.Deserialize<FramerInput>(httpRequest.Body); var output = new FramerOutput { framed = $"{framerInput.outer}{framerInput.inner}{framerInput.outer}" }; response = new APIGatewayProxyResponse { StatusCode = 200, Body = JsonSerializer.Serialize(output), Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } } }; } // 处理Function URL默认使用的API Gateway V2格式请求 else if (input is APIGatewayHttpApiV2ProxyRequest httpV2Request) { framerInput = JsonSerializer.Deserialize<FramerInput>(httpV2Request.Body); var output = new FramerOutput { framed = $"{framerInput.outer}{framerInput.inner}{framerInput.outer}" }; response = new APIGatewayHttpApiV2ProxyResponse { StatusCode = 200, Body = JsonSerializer.Serialize(output), Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } } }; } else { throw new InvalidOperationException("不支持的输入类型"); } return response; }; await LambdaBootstrapBuilder.Create(handler, new DefaultLambdaJsonSerializer()) .Build() .RunAsync(); public class FramerInput { public string inner { get; set; } public string outer { get; set; } } public class FramerOutput { public string framed { get; set; } }
步骤3:调整HTTP调用命令
GET请求通常不携带请求体,建议改用POST方式调用,curl命令修改为:
curl -X POST "https://xxx.lambda-url.us-east-1.on.aws/" -H "Content-type: application/json" -d '{"inner":"TEST_CURL","outer":"*"}'
说明
- 直接调用时,控制台或VS Toolkit会直接传递
FramerInput格式的JSON,代码会直接处理并返回FramerOutput - HTTP调用时,代码会识别API Gateway/Function URL的事件对象,解析请求体中的
FramerInput数据,处理后返回符合HTTP规范的响应格式
内容的提问来源于stack exchange,提问作者Pragmateek
相关产品推荐
相关产品推荐

