使用 在 Step Functions 中 AWS CDK 建立 Express 工作流程 - AWS Step Functions

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 在 Step Functions 中 AWS CDK 建立 Express 工作流程

在本教學課程中,您將了解如何使用 AWS Cloud Development Kit (AWS CDK) Infrastructure as Code (IAC) 架構,使用同步快速狀態機器建立 API Gateway REST API 做為後端整合。

您將使用 StepFunctionsRestApi 建構來將狀態機器連線至 API Gateway。StepFunctionsRestApi 建構將設定預設輸入/輸出映射和 API Gateway REST API,具有必要的許可和 HTTP "ANY" 方法。

使用 AWS CDK 是基礎設施即程式碼 (IAC) 架構,您可以使用程式設計語言定義 AWS 基礎設施。您可以使用其中一種 CDK 支援的語言定義應用程式,將程式碼合成至 CloudFormation 範本,然後將基礎設施部署至 AWS 您的帳戶。

您將使用 CloudFormation 定義 API Gateway REST API,該 API 與 Synchronous Express State Machine 整合為後端,然後使用 AWS 管理主控台 啟動執行。

開始本教學課程之前,請按照 AWS CDK - 先決條件入門所述設定您的 AWS CDK 開發環境,然後 AWS CDK 透過發出以下命令來安裝 :

npm install -g aws-cdk

步驟 1:設定您的 AWS CDK 專案

首先,為您的新 AWS CDK 應用程式建立目錄並初始化專案。

TypeScript
mkdir stepfunctions-rest-api cd stepfunctions-rest-api cdk init --language typescript
JavaScript
mkdir stepfunctions-rest-api cd stepfunctions-rest-api cdk init --language javascript
Python
mkdir stepfunctions-rest-api cd stepfunctions-rest-api cdk init --language python

初始化專案之後,請啟用專案的虛擬環境,並安裝 AWS CDK的基準相依性。

source .venv/bin/activate python -m pip install -r requirements.txt
Java
mkdir stepfunctions-rest-api cd stepfunctions-rest-api cdk init --language java
C#
mkdir stepfunctions-rest-api cd stepfunctions-rest-api cdk init --language csharp
Go
mkdir stepfunctions-rest-api cd stepfunctions-rest-api cdk init --language go
注意

請務必將目錄命名為 stepfunctions-rest-api。 AWS CDK 應用程式範本使用 目錄的名稱來產生來源檔案和類別的名稱。若使用不同名稱,您的應用程式將與本教學課程不相符。

現在安裝適用於 AWS Step Functions 和 Amazon API Gateway 的建構程式庫模組。

TypeScript
npm install @aws-cdk/aws-stepfunctions @aws-cdk/aws-apigateway
JavaScript
npm install @aws-cdk/aws-stepfunctions @aws-cdk/aws-apigateway
Python
python -m pip install aws-cdk.aws-stepfunctions python -m pip install aws-cdk.aws-apigateway
Java

編輯專案的 pom.xml,在現有的 <dependencies> 容器內新增下列相依性。

<dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>stepfunctions</artifactId> <version>${cdk.version}</version> </dependency> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>apigateway</artifactId> <version>${cdk.version}</version> </dependency>

Maven 會在您下次建立應用程式時自動安裝這些相依性。若要建置,發行 mvn compile 或使用您的 Java IDE 的 Build 命令。

C#
dotnet add src/StepfunctionsRestApi package Amazon.CDK.AWS.Stepfunctions dotnet add src/StepfunctionsRestApi package Amazon.CDK.AWS.APIGateway

您也可以使用 Visual Studio NuGet GUI 安裝指定的套件,可透過 Tools (工具) > NuGet Package Manager (NuGet 套件管理員) > Manage NuGet Packages for Solution (管理解決方案的 NuGet 套件) 獲取。

安裝模組後,您可以透過匯入下列套件,在 AWS CDK 應用程式中使用這些模組。

TypeScript
@aws-cdk/aws-stepfunctions @aws-cdk/aws-apigateway
JavaScript
@aws-cdk/aws-stepfunctions @aws-cdk/aws-apigateway
Python
aws_cdk.aws_stepfunctions aws_cdk.aws_apigateway
Java
software.amazon.awscdk.services.apigateway.StepFunctionsRestApi software.amazon.awscdk.services.stepfunctions.Pass software.amazon.awscdk.services.stepfunctions.StateMachine software.amazon.awscdk.services.stepfunctions.StateMachineType
C#
Amazon.CDK.AWS.StepFunctions Amazon.CDK.AWS.APIGateway
Go

將下列項目新增至 import內部stepfunctions-rest-api.go

"github.com/aws/aws-cdk-go/awscdk/awsapigateway" "github.com/aws/aws-cdk-go/awscdk/awsstepfunctions"

步驟 2:使用 建立具有同步快速狀態機器後端整合的 AWS CDK API Gateway REST API

首先,我們將介紹定義同步快速狀態機器和 API Gateway REST API 的個別程式碼片段,然後說明如何將這些程式碼放在您的 AWS CDK 應用程式中。然後,您將了解如何合成和部署這些資源。

注意

我們將在此處顯示的狀態機器是具有 Pass 狀態的簡單狀態機器。

建立快速狀態機器

這是定義具有 Pass 狀態之簡單狀態機器的 AWS CDK 程式碼。

TypeScript
const machineDefinition = new stepfunctions.Pass(this, 'PassState', { result: {value:"Hello!"}, }) const stateMachine = new stepfunctions.StateMachine(this, 'MyStateMachine', { definition: machineDefinition, stateMachineType: stepfunctions.StateMachineType.EXPRESS, });
JavaScript
const machineDefinition = new sfn.Pass(this, 'PassState', { result: {value:"Hello!"}, }) const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', { definition: machineDefinition, stateMachineType: stepfunctions.StateMachineType.EXPRESS, });
Python
machine_definition = sfn.Pass(self,"PassState", result = sfn.Result("Hello")) state_machine = sfn.StateMachine(self, 'MyStateMachine', definition = machine_definition, state_machine_type = sfn.StateMachineType.EXPRESS)
Java
Pass machineDefinition = Pass.Builder.create(this, "PassState") .result(Result.fromString("Hello")) .build(); StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine") .definition(machineDefinition) .stateMachineType(StateMachineType.EXPRESS) .build();
C#
var machineDefinition = new Pass(this, "PassState", new PassProps { Result = Result.FromString("Hello") }); var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps { Definition = machineDefinition, StateMachineType = StateMachineType.EXPRESS });
Go
var machineDefinition = awsstepfunctions.NewPass(stack, jsii.String("PassState"), &awsstepfunctions.PassProps { Result: awsstepfunctions.NewResult(jsii.String("Hello")), }) var stateMachine = awsstepfunctions.NewStateMachine(stack, jsii.String("StateMachine"), &awsstepfunctions.StateMachineProps { Definition: machineDefinition, StateMachineType: awsstepfunctions.StateMachineType_EXPRESS, })

您可以在此簡短的程式碼片段中看到:

  • 名為 的機器定義PassState,這是 Pass 狀態。

  • 狀態機器的邏輯名稱 MyStateMachine

  • 機器定義會用作狀態機器定義。

  • 狀態機器類型設定為 ,EXPRESS因為 StepFunctionsRestApi 只允許同步快速狀態機器。

使用 StepFunctionsRestApi 建構建立 API Gateway REST API

我們將使用 StepFunctionsRestApi 建構來建立具有必要許可和預設輸入/輸出映射的 API Gateway REST API。

TypeScript
const api = new apigateway.StepFunctionsRestApi(this, 'StepFunctionsRestApi', { stateMachine: stateMachine });
JavaScript
const api = new apigateway.StepFunctionsRestApi(this, 'StepFunctionsRestApi', { stateMachine: stateMachine });
Python
api = apigw.StepFunctionsRestApi(self, "StepFunctionsRestApi", state_machine = state_machine)
Java
StepFunctionsRestApi api = StepFunctionsRestApi.Builder.create(this, "StepFunctionsRestApi") .stateMachine(stateMachine) .build();
C#
var api = new StepFunctionsRestApi(this, "StepFunctionsRestApi", new StepFunctionsRestApiProps { StateMachine = stateMachine });
Go
awsapigateway.NewStepFunctionsRestApi(stack, jsii.String("StepFunctionsRestApi"), &awsapigateway.StepFunctionsRestApiProps { StateMachine = stateMachine, })

建置和部署 AWS CDK 應用程式

在您建立的 AWS CDK 專案中,編輯包含堆疊定義的檔案,使其看起來像下面的程式碼。您將從上方辨識 Step Functions 狀態機器和 API Gateway 的定義。

TypeScript

更新 lib/stepfunctions-rest-api-stack.ts,讀取如下。

import * as cdk from 'aws-cdk-lib'; import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions' import * as apigateway from 'aws-cdk-lib/aws-apigateway'; export class StepfunctionsRestApiStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const machineDefinition = new stepfunctions.Pass(this, 'PassState', { result: {value:"Hello!"}, }); const stateMachine = new stepfunctions.StateMachine(this, 'MyStateMachine', { definition: machineDefinition, stateMachineType: stepfunctions.StateMachineType.EXPRESS, }); const api = new apigateway.StepFunctionsRestApi(this, 'StepFunctionsRestApi', { stateMachine: stateMachine });
JavaScript

更新 lib/stepfunctions-rest-api-stack.js,讀取如下。

const cdk = require('@aws-cdk/core'); const stepfunctions = require('@aws-cdk/aws-stepfunctions'); const apigateway = require('@aws-cdk/aws-apigateway'); class StepfunctionsRestApiStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const machineDefinition = new stepfunctions.Pass(this, "PassState", { result: {value:"Hello!"}, }) const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', { definition: machineDefinition, stateMachineType: stepfunctions.StateMachineType.EXPRESS, }); const api = new apigateway.StepFunctionsRestApi(this, 'StepFunctionsRestApi', { stateMachine: stateMachine }); } } module.exports = { StepStack }
Python

更新 stepfunctions_rest_api/stepfunctions_rest_api_stack.py,讀取如下。

from aws_cdk import App, Stack from constructs import Construct from aws_cdk import aws_stepfunctions as sfn from aws_cdk import aws_apigateway as apigw class StepfunctionsRestApiStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) machine_definition = sfn.Pass(self,"PassState", result = sfn.Result("Hello")) state_machine = sfn.StateMachine(self, 'MyStateMachine', definition = machine_definition, state_machine_type = sfn.StateMachineType.EXPRESS) api = apigw.StepFunctionsRestApi(self, "StepFunctionsRestApi", state_machine = state_machine)
Java

更新 src/main/java/com.myorg/StepfunctionsRestApiStack.java,讀取如下。

package com.myorg; import software.amazon.awscdk.core.Construct; import software.amazon.awscdk.core.Stack; import software.amazon.awscdk.core.StackProps; import software.amazon.awscdk.services.stepfunctions.Pass; import software.amazon.awscdk.services.stepfunctions.StateMachine; import software.amazon.awscdk.services.stepfunctions.StateMachineType; import software.amazon.awscdk.services.apigateway.StepFunctionsRestApi; public class StepfunctionsRestApiStack extends Stack { public StepfunctionsRestApiStack(final Construct scope, final String id) { this(scope, id, null); } public StepfunctionsRestApiStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Pass machineDefinition = Pass.Builder.create(this, "PassState") .result(Result.fromString("Hello")) .build(); StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine") .definition(machineDefinition) .stateMachineType(StateMachineType.EXPRESS) .build(); StepFunctionsRestApi api = StepFunctionsRestApi.Builder.create(this, "StepFunctionsRestApi") .stateMachine(stateMachine) .build(); } }
C#

更新 src/StepfunctionsRestApi/StepfunctionsRestApiStack.cs,讀取如下。

using Amazon.CDK; using Amazon.CDK.AWS.StepFunctions; using Amazon.CDK.AWS.APIGateway; namespace StepfunctionsRestApi { public class StepfunctionsRestApiStack : Stack { internal StepfunctionsRestApi(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var machineDefinition = new Pass(this, "PassState", new PassProps { Result = Result.FromString("Hello") }); var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps { Definition = machineDefinition, StateMachineType = StateMachineType.EXPRESS }); var api = new StepFunctionsRestApi(this, "StepFunctionsRestApi", new StepFunctionsRestApiProps { StateMachine = stateMachine }); } } }
Go

更新 stepfunctions-rest-api.go,讀取如下。

package main import ( "github.com/aws/aws-cdk-go/awscdk" "github.com/aws/aws-cdk-go/awscdk/awsapigateway" "github.com/aws/aws-cdk-go/awscdk/awsstepfunctions" "github.com/aws/constructs-go/constructs/v3" "github.com/aws/jsii-runtime-go" ) type StepfunctionsRestApiGoStackProps struct { awscdk.StackProps } func NewStepfunctionsRestApiGoStack(scope constructs.Construct, id string, props *StepfunctionsRestApiGoStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // The code that defines your stack goes here var machineDefinition = awsstepfunctions.NewPass(stack, jsii.String("PassState"), &awsstepfunctions.PassProps { Result: awsstepfunctions.NewResult(jsii.String("Hello")), }) var stateMachine = awsstepfunctions.NewStateMachine(stack, jsii.String("StateMachine"), &awsstepfunctions.StateMachineProps{ Definition: machineDefinition, StateMachineType: awsstepfunctions.StateMachineType_EXPRESS, }); awsapigateway.NewStepFunctionsRestApi(stack, jsii.String("StepFunctionsRestApi"), &awsapigateway.StepFunctionsRestApiProps{ StateMachine = stateMachine, }) return stack } func main() { app := awscdk.NewApp(nil) NewStepfunctionsRestApiGoStack(app, "StepfunctionsRestApiGoStack", &StepfunctionsRestApiGoStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } // env determines the AWS environment (account+region) in which our stack is to // be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html func env() *awscdk.Environment { // If unspecified, this stack will be "environment-agnostic". // Account/Region-dependent features and context lookups will not work, but a // single synthesized template can be deployed anywhere. //--------------------------------------------------------------------------- return nil // Uncomment if you know exactly what account and region you want to deploy // the stack to. This is the recommendation for production stacks. //--------------------------------------------------------------------------- // return &awscdk.Environment{ // Account: jsii.String("account-id"), // Region: jsii.String("us-east-1"), // } // Uncomment to specialize this stack for the AWS Account and Region that are // implied by the current CLI configuration. This is recommended for dev // stacks. //--------------------------------------------------------------------------- // return &awscdk.Environment{ // Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), // Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), // } }

保存來源檔案,然後在應用程式的主目錄中發行 cdk synth。會 AWS CDK 執行應用程式並從中合成 CloudFormation 範本,然後顯示範本。

若要將 Amazon API Gateway 和 AWS Step Functions 狀態機器實際部署到您的 AWS 帳戶,請發出 cdk deploy。系統會要求您核准 AWS CDK 產生的 IAM 政策。

步驟 3:測試 API Gateway

使用同步快速狀態機器建立 API Gateway REST API 做為後端整合後,您可以測試 API Gateway。

使用 API Gateway 主控台測試部署的 API Gateway

  1. 開啟 Amazon API Gateway 主控台並登入。

  2. 選擇名為 的 REST APIStepFunctionsRestApi

  3. 資源窗格中,選擇 ANY方法。

  4. 選擇測試標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

  5. 針對 Method (方法) 選擇 POST

  6. 針對請求內文,複製下列請求參數。

    { "key": "Hello" }
  7. 選擇 Test (測試)。下列資訊會隨即顯示:

    • Request (請求) 是針對方法所呼叫的資源路徑。

    • Status (狀態) 是回應的 HTTP 狀態碼。

    • Latency (延遲) 是從發起人收到請求到傳回回應之間的時間。

    • 回應內文是 HTTP 回應內文。

    • 回應標頭是 HTTP 回應標頭。

    • 日誌會顯示模擬的 Amazon CloudWatch Logs 項目,如果是在 API Gateway 主控台之外呼叫此方法,則會寫入這些項目。

      注意

      雖然 CloudWatch Logs 項目是模擬的,但方法呼叫的結果是真實的。

回應內文輸出應該如下:

"Hello"
提示

嘗試使用不同的方法和無效的輸入來查看錯誤輸出。您可能想要變更狀態機器以尋找特定金鑰,並在測試期間提供錯誤的金鑰,讓狀態機器執行失敗,並在回應內文輸出中產生錯誤訊息。

使用 cURL 測試已部署的 API

  1. 開啟終端機視窗。

  2. 複製以下 cURL 命令,並將它貼到終端機視窗,同時將 <api-id> 取代為您 API 的 API ID,以及將 <region> 取代為 API 的部署區域。

    curl -X POST\ 'https://<api-id>.execute-api.<region>.amazonaws.com/prod' \ -d '{"key":"Hello"}' \ -H 'Content-Type: application/json'

回應內文輸出應該如下所示:

"Hello"
提示

嘗試使用不同的方法和無效的輸入來查看錯誤輸出。您可能想要變更狀態機器以尋找特定金鑰,並在測試期間提供錯誤的金鑰,讓狀態機器執行失敗,並在回應內文輸出中產生錯誤訊息。

步驟 4:清除

完成嘗試 API Gateway 後,您可以使用 AWS CDK 來銷毀狀態機器和 API Gateway。在您的應用程式的主目錄中發行 cdk destroy