AWS API Gateway with Step Function

前端 未结 3 1889
刺人心
刺人心 2021-01-02 21:13

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

相关标签:
3条回答
  • 2021-01-02 21:37

    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

    0 讨论(0)
  • 2021-01-02 21:51

    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.

    0 讨论(0)
  • 2021-01-02 21:55

    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.

    0 讨论(0)
提交回复
热议问题