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
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: contacto@patagonia-it.com
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
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.
Instead of directly exposing your step function via API Gateway by choosing API Gateway Integration Type "AWS Service", create a Lambda function that calls your Step Function and expose that Lambda function via API Gateway using Integration Type "Lambda". Then you can configure your API Gateway and Lambda function to accept whatever input format that you desire and you could hard-code the stateMacheArn value in your Lambda function or set it as a Lambda environment variable, so that the API Gateway consumer doesn't need to know anything about the ARN.