Serverless部署AWS Lambda时如何修改handler返回响应体
问题根因
问题出在Lambda handler的异步逻辑处理错误:
- 你定义的handler是
async异步函数,但调用awsServerlessExpress.proxy时既没有等待其执行完成,也没有返回其执行结果 awsServerlessExpress.proxy默认是非阻塞调用:请求转发到express后,路由里的console.log会同步执行打印到CloudWatch,但res.json()生成的响应体还没回传给Lambda运行时,async函数就已经执行完毕返回undefined,API Gateway收到空值后默认返回200状态码+空响应体。- 现有代码每次请求都会新建express server实例,会额外增加冷启动耗时,也存在内存泄漏风险。
修复方案
1. 修改src/index.ts的handler逻辑
调整代码如下,核心是让handler等待proxy处理完成并返回完整响应,同时缓存server实例、关闭事件循环空等配置:
// 把server实例缓存到全局,避免重复创建 let cachedServer: any = null; const databaseconnect = async () => { if (!DatabaseService.isConnected) { await DatabaseService.getConnection(); } // 其余数据库初始化逻辑保持不变 if (!cachedServer) { cachedServer = awsServerlessExpress.createServer(app); } return cachedServer; }; exports.handler = async (event: any, context: any) => { // 禁止Lambda等待事件循环为空再返回,避免数据库长连接导致函数超时 context.callbackWaitsForEmptyEventLoop = false; const server = await databaseconnect(); // 传入PROMISE参数让proxy返回Promise,await拿到完整响应后返回给Lambda return awsServerlessExpress.proxy(server, event, context, 'PROMISE'); };
如果你使用的是较早版本的
aws-serverless-express,proxy参数顺序有差异,上面的PROMISE参数传参报错的话,替换为return awsServerlessExpress.proxy(server, event, context, null, 'PROMISE');即可。
2. 无需修改的配置说明
- 你当前的
serverless.yml配置是正确的,http事件默认启用Lambda代理集成,支持透传express返回的状态码、响应头和响应体,不需要调整 - 路由和控制器代码逻辑没有问题,只要handler正确返回proxy的处理结果,
res.json()的内容就会正常返回给客户端
验证方式
修改完成后重新执行serverless deploy部署,再发起POST请求到对应接口,即可在200响应中拿到预期的JSON响应体。
内容的提问来源于stack exchange,提问作者Harsh Upparwal
相关产品推荐
相关产品推荐

