如何通过AWS CDK配置API Gateway返回Step Function Lambda链结果
问题分析与解决方案
你遇到的核心问题是API Gateway使用了异步的Step Functions集成方式,默认返回状态机执行的启动元数据而非执行结果,同时状态机的最终输出未正确指向exampleFn2的返回值。结合你使用的Express类型状态机(支持同步执行),可通过以下两步修改解决:
1. 将API Gateway集成改为同步执行模式
原代码用StepFunctionsIntegration.startExecution是异步启动状态机的方式,API会立即返回执行ARN等信息,不会等待状态机执行完成。需替换为同步执行集成StepFunctionsIntegration.executeSync,让API Gateway等待状态机执行完毕后返回结果。
2. 调整状态机输出,确保最终返回exampleFn2的结果
默认情况下,LambdaInvoke任务的输出包含完整的Lambda响应结构(如Payload、StatusCode),需要通过outputPath指定状态机的最终输出为exampleFn2的返回内容。
修改后的完整CDK代码示例
const exampleFn = new NodejsFunction(this, "exampleFn", {}); const exampleFn2 = new NodejsFunction(this, "exampleFn2", {}); // 调整状态机定义:为第二个LambdaInvoke设置outputPath,指向Lambda的返回结果 const machineDefinition = new LambdaInvoke(this, "exampleFnInvokeTask", { lambdaFunction: exampleFn }).next( new LambdaInvoke(this, "exampleFnInvokeTask2", { lambdaFunction: exampleFn2, inputPath: "$.Payload", // 指定状态机最终输出为exampleFn2的完整返回值 outputPath: "$.Payload" }) ); const stateMachine = new sfn.StateMachine(this, "StateMachine", { stateMachineName: "stateMachine", stateMachineType: sfn.StateMachineType.EXPRESS, definitionBody: sfn.DefinitionBody.fromChainable(machineDefinition) }); // 替换为同步执行集成,并配置响应模板从状态机输出中提取数据 const stepFunctionIntegration = StepFunctionsIntegration.executeSync( stateMachine, { // 将API请求体直接作为状态机的输入 requestTemplates: { "application/json": "$input.json('$')" }, integrationResponses: [ { statusCode: "200", // 解析状态机输出中的body字段(因为exampleFn2返回的body是JSON字符串) responseTemplates: { "application/json": "$util.parseJson($input.json('$.output.body'))" } } ] } ); const callbackEnd = api.root.addResource("callback"); const _ = callbackEnd.addMethod("POST", stepFunctionIntegration);
关键细节说明
- 同步集成的必要性:Express状态机支持同步执行(最大超时5分钟),
executeSync会让API Gateway阻塞等待状态机执行完成,直接返回执行的最终输出。 - outputPath的作用:
outputPath: "$.Payload"让第二个LambdaInvoke任务的输出仅保留Lambda函数返回的内容,而非整个Lambda调用的响应结构(包含Payload、StatusCode等元数据)。 - 响应模板解析:因为
exampleFn2返回的body是JSON字符串,所以用$util.parseJson()将其解析为JSON对象,确保API返回结构化数据而非字符串。
如果需要返回exampleFn2的完整响应(包括statusCode和headers),可将响应模板改为:
"application/json": "$input.json('$.output')"
内容的提问来源于stack exchange,提问作者Rafael R. Camargo
相关产品推荐
相关产品推荐

