如何为Amplify GraphQL触发的Serverless解析器事件做类型定义
AWS Lambda中AppSyncResolverEvent类型与实际事件不匹配的问题解析
问题描述
我正在给AWS Amplify/Next.js前端发送、Node.js AWS Lambda接收的事件对象定义类型,使用了aws-lambda包中的AppSyncResolverEvent接口,但它和实际收到的事件结构不匹配,想知道问题出在哪。
细节补充
前端(Next.js)通过aws-amplify和@aws-amplify/api-graphql触发事件的代码:
import { graphqlOperation, GraphQLResult } from "@aws-amplify/api-graphql"; // 版本:2.3.11 import { API } from "aws-amplify"; // 版本:^4.3.28 ... // 从Lambda获取Schema const response = (await API.graphql<{ myAppSyncFunctionResponse: any }>( graphqlOperation(myAppSyncFunction), { input: "foo" } )) as GraphQLResult<{ myAppSyncFunctionResponse: string }>;
Lambda实际接收到的事件结构:
{ typeName: "Mutation", fieldName: "myAppSyncFunction", arguments: { input: { ... } }, identity: {...}, source: ..., request: ..., prev:... }
但aws-lambda包中AppSyncResolverEvent的类型定义结构如下:
// node_modules/@types/aws-lambda/trigger/appsync-resolver.d.ts { arguments: TArguments; identity?: AppSyncIdentity; source: TSource; request: { headers: AppSyncResolverEventHeaders; }; info: { selectionSetList: string[]; selectionSetGraphQL: string; parentTypeName: string; fieldName: string; variables: { [key: string]: any }; }; prev: { result: { [key: string]: any } } | null; stash: { [key: string]: any }; }
问题根源
差异来自AppSync与Lambda集成的两种不同模式:
- 你当前用的是直接Lambda数据源模式,这种模式下Lambda收到的事件会把
typeName、fieldName等核心字段放在顶层。 - 而
aws-lambda包中的AppSyncResolverEvent类型,对应的是**AppSync管道解析器(Pipeline Resolver)**模式的事件结构——该模式会把typeName(对应parentTypeName)、fieldName等字段封装在info对象内部。
解决方法
方案1:自定义匹配实际结构的类型
如果继续使用直接Lambda数据源,直接定义匹配实际事件的类型即可:
// 自定义直接Lambda数据源的事件类型 import type { AppSyncIdentity, AppSyncResolverEventHeaders } from "aws-lambda"; interface AppSyncDirectLambdaEvent<TArguments = Record<string, any>> { typeName: string; fieldName: string; arguments: TArguments; identity?: AppSyncIdentity; source?: Record<string, any>; request?: { headers?: AppSyncResolverEventHeaders; }; prev?: { result?: Record<string, any> } | null; } // 在Lambda函数中使用 export async function eventBridgeResolver( event: AppSyncDirectLambdaEvent<{ input: string }> ) { // 示例逻辑:访问顶层的typeName和fieldName console.log(`处理${event.typeName}类型下的${event.fieldName}字段请求`); return { success: true }; }
方案2:切换到管道解析器模式
如果想复用AppSyncResolverEvent类型,可以把AppSync的集成方式改成管道解析器。但这需要调整AppSync的配置,重新定义Resolver的流水线步骤,适合需要复杂解析逻辑的场景。
额外提示
建议升级aws-lambda包到最新稳定版,部分旧版本的类型定义可能没有覆盖所有AppSync集成场景,避免因类型定义滞后导致的不匹配问题。
内容的提问来源于stack exchange,提问作者JimmyTheCode
相关产品推荐
相关产品推荐

