【问题标题】:AWS API Gateway with Step Function带有 Step Function 的 AWS API 网关
【发布时间】:2017-11-20 04:11:11
【问题描述】:

我想要一个将 AWS API Gateway 与 Step Function 集成的示例。我已阅读本教程 Creating a Step Functions API Using API Gateway 但该教程需要我以

格式发送请求
{    
"input": "{}",    
"name": "PostmanExecution",    
"stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:Custom" 
}

我想发送正常的请求,并且只在 API Gateway 中配置这个 stateMachineArn,这样客户端就不需要发送这个了。

【问题讨论】:

    标签: amazon-web-services aws-lambda aws-api-gateway aws-step-functions


    【解决方案1】:

    我设法通过使用 API Gateway 公开了 2 个端点,一个用于启动执行,第二个用于检查执行状态。

    此操作无需使用 lambda,也无需通过参数指示步骤函数。

    解决方案 CloudFormation 模板为:

    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
    

    OpenAPI 配置是:

    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'
    

    我在https://github.com/jvillane/aws-sam-step-functions-lambda 的 github 中提交了一个工作示例

    【讨论】:

      【解决方案2】:

      创建您的 API Gateway 资源和方法。然后在“方法执行”设置中,在集成请求中,使用以下设置:

      • 集成类型:AWS 服务
      • AWS 区域:您的区域
      • AWS 服务:Step Functions
      • AWS 子域:你的子域,如果你有 - 我把它留空
      • HTTP 方法:POST
      • 操作:开始执行
      • 执行角色:需要是具有 StepFunction 启动执行策略的角色,例如 arn:aws:iam::aws:policy/AWSStepFunctionsFullAccess
      • 凭据缓存:我将其保留为默认值
      • 内容处理:直通

      然后是魔法。再往下,在 Body Mapping Templates 下:

      • 请求正文直通:从不
      • 添加映射模板:application/json

      在模板文本框中进一步向下:

      #set($input = $input.json('$'))
      {
         "input": "$util.escapeJavaScript($input)",
         "stateMachineArn": "arn:aws:states:eu-west-1:123456789012:stateMachine:yourStepFunctionName"
      }
      

      这会将发布到 API Gateway 的 json 有效负载传递给 Step Function。

      省略执行名称,以便每次调用 API Gateway 都会创建一个新的执行。

      【讨论】:

      • 知道如何将您的 resourceTemplate 添加到 CloudFormation 模板吗?
      • @Console 我刚刚发布了一个使用 CloudFormation 的可行解决方案
      • 我想用动态填充区域和帐户 ID 来形成 stateMachineArn。我能够从 $context.accountId 获取帐户 ID,但找不到任何提供当前区域名称的内容。在我的模板中stateMachineArn 现在看起来像这样,"arn:aws:states:us-east-1:$context.accountId:stateMachine:AbcStateMachine" 知道如何动态获取当前区域。
      • 您知道如何在输入中添加额外的参数吗?例如,认知用户电子邮件: ($context.authorizer.claims.email) 它必须在“输入”中,因为这是传递给 lambda 的内容。不知道该怎么做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-26
      • 2015-12-30
      • 2019-07-03
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      相关资源
      最近更新 更多