Apollo GraphQL Lambda Handler报错:Cannot read property 'method' of undefined
问题:AWS Lambda中Apollo GraphQL服务器返回"Cannot read property 'method' of undefined"错误
我尝试在AWS Lambda中运行Apollo GraphQL服务器,使用@as-integrations/aws-lambda库,同时通过CDK部署Lambda与REST API Gateway。
基础设施代码
const helloFunction = new NodejsFunction(this, 'lambda', { entry: path.join(__dirname, "lambda.ts"), handler: "handler" }); new LambdaRestApi(this, 'apigw', { handler: helloFunction, });
Lambda实现代码
const typeDefs = `#graphql type Query { hello: String }`; const resolvers = { Query: { hello: () => 'world', }, }; const server = new ApolloServer({ typeDefs, resolvers, introspection: true, }) console.log('###? running lambda') export const handler = startServerAndCreateLambdaHandler( server, handlers.createAPIGatewayProxyEventV2RequestHandler(), { middleware: [ async (event) => { console.log('###? received event=' + JSON.stringify(event, null, 2)) return async (result) => { console.log(("###? result=" + JSON.stringify(result, null, 2))) result } } ] });
错误信息
当向端点POST合适的查询时,得到如下错误:
{ "statusCode": 400, "body": "Cannot read property 'method' of undefined" }
Lambda日志已正常输出,确认错误来自startServerAndCreateLambdaHandler的返回结果,代码基于官方示例编写但运行失败,求助原因及解决方法。
原因分析
核心问题是API Gateway事件版本不匹配:
- Lambda代码中使用的
handlers.createAPIGatewayProxyEventV2RequestHandler(),是用于处理**API Gateway V2(HttpApi)**的事件格式。 - 但CDK的
LambdaRestApi默认创建的是REST API(V1),触发Lambda时传递的是V1格式事件,与V2结构差异明显,导致Apollo代码尝试读取event.requestContext.http.method时找不到对应属性,抛出错误。
另外,你写的中间件存在小问题:返回的函数中没有return result,会导致响应内容丢失,需要修正。
解决方法
方法一:改用API Gateway V1请求处理器
保持CDK的REST API(V1)不变,修改Lambda代码中的请求处理器为V1版本:
export const handler = startServerAndCreateLambdaHandler( server, // 替换为V1处理器 handlers.createAPIGatewayProxyEventRequestHandler(), { middleware: [ async (event) => { console.log('###? received event=' + JSON.stringify(event, null, 2)) return async (result) => { console.log("###? result=" + JSON.stringify(result, null, 2)) // 必须返回result,否则响应无内容 return result } } ] });
方法二:改用API Gateway V2(HttpApi)
保持Lambda代码的V2处理器不变,修改CDK代码创建HttpApi而非REST API:
import { HttpApi } from 'aws-cdk-lib/aws-apigatewayv2'; import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations'; const helloFunction = new NodejsFunction(this, 'lambda', { entry: path.join(__dirname, "lambda.ts"), handler: "handler" }); // 替换LambdaRestApi为HttpApi new HttpApi(this, 'apigw', { defaultIntegration: new HttpLambdaIntegration('lambda-integration', helloFunction), });
同时记得修正Lambda中间件的return result问题。
内容的提问来源于stack exchange,提问作者Przemek Lach
相关产品推荐
相关产品推荐

