Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS API Gateway with Step Function

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.

like image 983
Balkrishna Avatar asked Jun 17 '17 13:06

Balkrishna


People also ask

Can AWS API gateway call STEP function?

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.

Can API gateway trigger Step Functions?

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.

How do you call a step function in API?

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.


2 Answers

Create your API Gateway resource and method. Then in the "Method Execution" settings, in the Integration Request, use these settings:

  • Integration type: AWS Service
  • AWS Region: your region
  • AWS Service: Step Functions
  • AWS Subdomain: your subdomain if you have one - I left it blank
  • HTTP method: POST
  • Action: StartExecution
  • Execution role: needs to be a role with StepFunction start execute policy, such as arn:aws:iam::aws:policy/AWSStepFunctionsFullAccess
  • Credentials cache: I left this as default
  • Content Handling: Passthrough

Then the magic. Futher down, under Body Mapping Templates:

  • Request body passthrough: Never
  • Add mapping template : application/json

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.

like image 135
Lee Oades Avatar answered Oct 12 '22 13:10

Lee Oades


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

like image 43
Julio Villane Avatar answered Oct 12 '22 13:10

Julio Villane