LocalStack中API Gateway调用Step Function报错求助
问题描述
在LocalStack中通过API Gateway调用Step Function时,执行curl请求返回以下错误:
{"Type": "User", "message": "Error invoking integration for API Gateway ID '5zpknu8ld7': Expecting value: line 1 column 1 (char 0)", "__type": "InvalidRequest"}
初始化脚本
#!/bin/bash set -x apt-get install jq -y source ~/.bashrc export STEP_FUNCTION_DEFINITION=$(</etc/localstack/init/functions/step-func-def.json) awslocal lambda create-function \ --function-name lambda-function \ --runtime python3.10 \ --zip-file fileb:///etc/localstack/init/functions/function.zip \ --handler handler.lambda_handler \ --role arn:aws:iam::000000000000:role/lambda-role awslocal stepfunctions create-state-machine \ --name step-function \ --definition "$STEP_FUNCTION_DEFINITION" \ --role-arn arn:aws:iam::000000000000:role/step-function-role export gateway_repsonse=$(awslocal apigateway create-rest-api --name api-gateway) export gateway_id=$(echo $gateway_repsonse | jq -r '.id') export root_resources_response=$(awslocal apigateway get-resources --rest-api-id $gateway_id) export root_resource_id=$(echo $root_resources_response | jq -r '.items[0].id') export session_resource_response=$(awslocal apigateway create-resource \ --rest-api-id $gateway_id \ --parent-id $root_resource_id \ --path-part "{sessionId}") export session_resource_id=$(echo $session_resource_response | jq -r '.id') awslocal apigateway put-method \ --rest-api-id $gateway_id \ --resource-id $session_resource_id \ --http-method POST \ --request-parameters "method.request.path.sessionId=true" \ --authorization-type "NONE" awslocal apigateway put-integration \ --rest-api-id $gateway_id \ --resource-id $session_resource_id \ --http-method POST \ --type AWS \ --integration-http-method POST \ --uri arn:aws:apigateway:us-east-1:states:action/StartExecution \ --request-parameters '{"input": "{}","name": "MyExecution","stateMachineArn": "arn:aws:states:us-east-1:000000000000:stateMachine:step-function"}' \ --passthrough-behavior WHEN_NO_MATCH awslocal apigateway create-deployment \ --rest-api-id $gateway_id \ --stage-name test set +x
Step Function定义
{ "StartAt": "QueryBMM", "States": { "QueryBMM": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": { "Payload.$": "$", "FunctionName": "arn:aws:lambda:us-east-1:000000000000:function:step-function-handler" }, "Retry": [ { "ErrorEquals": [ "Lambda.ServiceException", "Lambda.AWSLambdaException", "Lambda.SdkClientException", "Lambda.TooManyRequestsException" ], "IntervalSeconds": 2, "MaxAttempts": 6, "BackoffRate": 2 } ], "End": true } } }
执行的curl命令
curl -X POST http://localhost:4566/restapis/<gateway_id>/test/_user_request_/test
预期Step Function和Lambda被触发,但实际返回上述错误。
问题排查与修复
1. API Gateway集成参数配置错误
当前put-integration命令中的--request-parameters格式不符合AWS API Gateway规则:
- AWS类型集成需要通过**请求模板(requestTemplates)**构造服务请求体,而非直接用
request-parameters传递参数; request-parameters的键需以integration.request.开头,不能直接写input等参数名。
修复后的put-integration命令:
awslocal apigateway put-integration \ --rest-api-id $gateway_id \ --resource-id $session_resource_id \ --http-method POST \ --type AWS \ --integration-http-method POST \ --uri arn:aws:apigateway:us-east-1:states:action/StartExecution \ --request-templates '{"application/json": "{\"input\": \"$input.json(''$'')\", \"name\": \"MyExecution\", \"stateMachineArn\": \"arn:aws:states:us-east-1:000000000000:stateMachine:step-function\"}"}' \ --passthrough-behavior WHEN_NO_MATCH
该配置会将API Gateway收到的请求体作为Step Function输入,同时指定执行名称和状态机ARN。
2. curl请求缺少有效请求体
错误提示"Expecting value: line 1 column 1"说明API Gateway未收到有效JSON请求体,导致集成无法构造合法的StartExecution请求。
修复后的curl命令:
curl -X POST http://localhost:4566/restapis/<gateway_id>/test/_user_request_/test -H "Content-Type: application/json" -d "{}"
3. Step Function中的Lambda ARN不匹配
初始化脚本创建的Lambda名称为lambda-function,但Step Function定义中引用的ARN是arn:aws:lambda:us-east-1:000000000000:function:step-function-handler,名称不一致会导致Step Function执行失败。
修复后的Step Function定义片段:
"FunctionName": "arn:aws:lambda:us-east-1:000000000000:function:lambda-function"
4. 路径参数未使用(可选优化)
脚本创建了带{sessionId}路径参数的资源,但当前集成未使用该参数。若需将sessionId传入Step Function,可修改request-templates:
{"application/json": "{\"input\": {\"sessionId\": \"$input.params(''path'').sessionId\", \"body\": $input.json(''$'')}, \"name\": \"MyExecution-$$context.requestId\", \"stateMachineArn\": \"arn:aws:states:us-east-1:000000000000:stateMachine:step-function\"}"}
内容的提问来源于stack exchange,提问作者Thomas Turner
相关产品推荐
相关产品推荐

