I want a sample to integrate AWS API Gateway with Step Function. I have read this tutorial Creating a Step Functions API Using API Gateway but that tutorial needs me to send request in format of
{
"input": "{}",
"name": "PostmanExecution",
"stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:Custom"
}
I want to send normal request and configure this stateMachineArn in API Gateway only, so that clients dont need to send this.
Conclusion. The Step Functions integration with API Gateway provides customers with the ability to call REST APIs and HTTP APIs directly from a Step Functions workflow. Step Functions' built in error handling helps developers reduce code and decouple business logic.
You can use Amazon API Gateway to associate your AWS Step Functions APIs with methods in an API Gateway API. When an HTTPS request is sent to an API method, API Gateway invokes your Step Functions API actions.
Open the Step Functions console and choose Create state machine. Choose Run a sample project, and then choose Make a call to API Gateway. The state machine Code and Visual Workflow are displayed. Choose Next.
Create your API Gateway resource and method. Then in the "Method Execution" settings, in the Integration Request, use these settings:
Then the magic. Futher down, under Body Mapping Templates:
Futher down in the template text box:
#set($input = $input.json('$'))
{
"input": "$util.escapeJavaScript($input)",
"stateMachineArn": "arn:aws:states:eu-west-1:123456789012:stateMachine:yourStepFunctionName"
}
This will pass the json payload posted to API Gateway through to the Step Function.
Omit the execution name so that each call to API Gateway creates a new execution.
I managed to expose 2 endpoints by using API Gateway, one to start the execution and the second to check the execution status.
There is no need to use a lambda for this actions nor indicate the step function arn by parameters.
The solution CloudFormation template is:
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: >
The turtle calculator, a dummy slow calculator for comprehensive code example
Parameters:
OpenAPIS3File:
Description: '"openapi.yaml" file location'
Default: ./openapi.yaml
Type: String
Resources:
Workflow:
Type: AWS::StepFunctions::StateMachine
Properties:
StateMachineName: !Sub ${AWS::StackName}-state-machine
RoleArn: !GetAtt StateExecutionRole.Arn
DefinitionString: !Sub |
{
...
}
Api:
Type: AWS::Serverless::Api
Properties:
StageName: random-workflow
Name: !Sub ${AWS::StackName}-api
DefinitionBody:
'Fn::Transform':
Name: AWS::Include
Parameters:
Location: !Ref OpenAPIS3File
And the OpenAPI configuration is:
openapi: 3.0.1
info:
title: Api Mocker
description: Automated testing application for TGR
contact:
name: Patagonia-IT
url: http://www.patagonia-it.com
email: [email protected]
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.0
x-amazon-apigateway-request-validators:
params:
validateRequestParameters: true
validateRequestBody: false
x-amazon-apigateway-request-validator: params
paths:
/workflow:
post:
x-amazon-apigateway-integration:
credentials:
Fn::GetAtt: [ ApiGatewayStepFunctionsRole, Arn ]
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:states:action/StartExecution
httpMethod: POST
type: aws
responses:
default:
statusCode: 200
responseTemplates:
application/json: |
'{ "executionId": "$input.json('executionArn').split(':').get(7) }'
requestTemplates:
application/json:
Fn::Sub: |-
{
"input": "$util.escapeJavaScript($input.json('$'))",
"name": "$context.requestId",
"stateMachineArn": "${Workflow}"
}
summary: Start workflow instance
responses:
200:
$ref: '#/components/responses/200Execution'
403:
$ref: '#/components/responses/Error'
/workflow/{executionId}:
get:
x-amazon-apigateway-integration:
credentials:
Fn::GetAtt: [ ApiGatewayStepFunctionsRole, Arn ]
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:states:action/DescribeExecution
httpMethod: POST
type: aws
responses:
default:
statusCode: 200
responseTemplates:
application/json: |-
#set ($status = $input.json('status'))
{
#if($status == '"SUCCEEDED"')
"output": $util.parseJson($input.json('output')),
#end
"status": $status
}
requestTemplates:
application/json:
Fn::Sub: |-
{
"executionArn": "arn:aws:states:${AWS::Region}:${AWS::AccountId}:execution:${Workflow.Name}:$input.params().path.get('executionId')"
}
summary: Workflow execution status
responses:
200:
$ref: '#/components/responses/200ExecutionDetails'
I have commited a working example in github in https://github.com/jvillane/aws-sam-step-functions-lambda
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With