.NET 6 Minimal API如何获取APIGatewayProxyRequest参数
.NET 6 Minimal API 部署到AWS Lambda时获取APIGatewayProxyRequest的方法
问题原因
Minimal API的默认参数绑定逻辑只会从HTTP请求的路由参数、查询字符串、请求体、请求头中绑定参数值,不会自动识别Lambda入口接收到的原始APIGatewayProxyRequest对象,因此直接在端点委托中声明该类型参数无法拿到实例。
实现步骤
- 安装依赖NuGet包
首先确保项目安装了以下两个适配包:Amazon.Lambda.APIGatewayEvents:提供APIGatewayProxyRequest等API Gateway事件类型定义Amazon.Lambda.AspNetCoreServer:提供ASP.NET Core和Lambda运行时的适配能力
- 自定义Lambda入口类,将原始请求写入HttpContext
新建Lambda入口类继承自APIGatewayProxyFunction,重写对应方法把每个请求的原始API Gateway事件、Lambda上下文存入当前请求的HttpContext.Items集合,这个集合是请求级别的隔离存储,不会出现多请求串数据的问题:
using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.AspNetCoreServer; using Amazon.Lambda.Core; using Microsoft.AspNetCore.Http; public class LambdaEntry : APIGatewayProxyFunction { protected override void PostCreateContext(HostBuilderContext hostContext, IApplicationBuilder appBuilder, APIGatewayProxyRequest apiRequest, ILambdaContext lambdaContext) { appBuilder.Use(async (httpContext, next) => { httpContext.Items["APIGatewayRequest"] = apiRequest; httpContext.Items["LambdaContext"] = lambdaContext; await next(); }); } protected override void Init(IWebHostBuilder webHostBuilder) { // 指向Minimal API的Program配置 webHostBuilder.UseStartup<Program>(); } }
- 在Minimal API端点中通过HttpContext获取对象
端点委托中注入HttpContext,从Items中取出之前存入的APIGatewayProxyRequest实例即可使用:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/students/{name}", async (HttpContext httpContext) => { // 取出原始API Gateway请求 var apiRequest = httpContext.Items["APIGatewayRequest"] as APIGatewayProxyRequest; if (apiRequest == null) { return Results.StatusCode(500); } // 正常使用请求对象,比如取请求ID、stage变量、身份信息等 var awsRequestId = apiRequest.RequestContext.RequestId; var name = httpContext.Request.RouteValues["name"]?.ToString(); return Results.Ok(new { Name = name, AwsRequestId = awsRequestId }); }); app.Run(); // 补充Lambda入口适配所需的声明 public partial class Program { }
优化建议
如果需要在多个端点频繁获取该对象,可以封装一个HttpContext扩展方法减少重复代码:
public static class AwsLambdaHttpContextExtensions { public static APIGatewayProxyRequest GetAPIGatewayRequest(this HttpContext context) { if (context.Items.TryGetValue("APIGatewayRequest", out var request) && request is APIGatewayProxyRequest apiRequest) { return apiRequest; } throw new InvalidOperationException("当前请求非API Gateway触发的Lambda请求"); } }
使用时直接调用即可:
app.MapGet("/test", (HttpContext context) => { var apiRequest = context.GetAPIGatewayRequest(); // 业务逻辑 return Results.Ok(); });
注意:不要将
APIGatewayProxyRequest注册为全局/作用域服务,Lambda运行时存在实例复用机制,全局注册会出现不同请求数据污染的问题,存入HttpContext.Items是最安全的方式。
内容的提问来源于stack exchange,提问作者thunderbolt
相关产品推荐
相关产品推荐

