

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS CDK 를 사용하여 Step Functions에서 Express 워크플로 생성
<a name="tutorial-step-functions-rest-api-integration-cdk"></a>

이 자습서에서는 코드형 AWS Cloud Development Kit (AWS CDK) 인프라(IAC) 프레임워크를 사용하여 동기식 Express 상태 시스템을 백엔드 통합으로 사용하여 API Gateway REST API를 생성하는 방법을 알아봅니다.

`StepFunctionsRestApi` 구조를 사용하여 상태 시스템을 API Gateway에 연결합니다. `StepFunctionsRestApi` 구조는 필수 권한 및 HTTP “ANY” 메서드와 함께 기본 입력/출력 매핑과 API Gateway REST API를 설정합니다.

 AWS CDK 는 코드형 인프라(IAC) 프레임워크이므로 프로그래밍 언어를 사용하여 AWS 인프라를 정의합니다. CDK에서 지원하는 언어 중 하나로 앱을 정의하고 코드를 CloudFormation 템플릿으로 합성한 다음 AWS 계정에 인프라를 배포합니다.

 CloudFormation 를 사용하여 동기 Express 상태 시스템과 백엔드로 통합된 API Gateway REST API를 정의한 다음를 사용하여 실행 AWS Management Console 을 시작합니다.

이 자습서를 시작하기 전에 [AWS CDK 사전 조건 시작하기](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_prerequisites)에 설명된 대로 AWS CDK 개발 환경을 설정한 다음 다음을 실행 AWS CDK 하여를 설치합니다.

```
npm install -g aws-cdk
```

## 1단계: AWS CDK 프로젝트 설정
<a name="step-functions-rest-api-integration-cdk-step-1"></a>

먼저 새 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\$1 ]

```
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\$1 ]

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

Visual Studio NuGet GUI를 사용해 표시된 패키지를 설치할 수도 있습니다. Visual Studio NuGet GUI는 **도구(Tools)** > **NuGet 패키지 관리자(NuGet Package Manager)** > **솔루션용 NuGet 패키지 관리(Manage NuGet Packages for Solution)**에서 사용할 수 있습니다.

------

모듈을 설치한 후에는 다음 패키지를 가져와서 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\$1 ]

```
Amazon.CDK.AWS.StepFunctions
Amazon.CDK.AWS.APIGateway
```

------
#### [ Go ]

다음을 `stepfunctions-rest-api.go` 내 `import`에 추가합니다.

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

------

## 2단계: AWS CDK 를 사용하여 동기 Express 상태 시스템 백엔드 통합으로 API Gateway REST API 생성
<a name="step-functions-rest-api-integration-cdk-step-2"></a>

먼저 동기 Express 상태 시스템과 API Gateway REST API를 정의하는 개별 코드 조각을 살펴본 다음 이를 AWS CDK 앱에 함께 배치하는 방법을 설명하겠습니다. 그런 다음 이러한 리소스를 합성하고 배포하는 방법을 알아보겠습니다.

**참고**  
여기에 표시되는 상태 시스템은 `Pass` 상태가 있는 단순한 상태 시스템입니다.

### Express 상태 시스템 만들기
<a name="step-functions-rest-api-integration-cdk-create-state-machine"></a>

상태가 있는 간단한 상태 시스템을 정의하는 AWS CDK 코드입니다`Pass`.

------
#### [ 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\$1 ]

```
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`)
+ 상태 시스템 정의로 사용되는 시스템 정의
+ `StepFunctionsRestApi`에서 동기 Express 상태 시스템만 허용하기 때문에 `EXPRESS`로 설정된 상태 시스템 유형

### `StepFunctionsRestApi` 구성을 사용하여 API Gateway REST API 만들기
<a name="step-functions-rest-api-integration-cdk-create-rest-api"></a>

`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\$1 ]

```
var api = new StepFunctionsRestApi(this, "StepFunctionsRestApi", new StepFunctionsRestApiProps
{
    StateMachine = stateMachine
});
```

------
#### [ Go ]

```
awsapigateway.NewStepFunctionsRestApi(stack, jsii.String("StepFunctionsRestApi"), &awsapigateway.StepFunctionsRestApiProps
{
    StateMachine = stateMachine,
})
```

------

### AWS CDK 앱을 빌드하고 배포하려면
<a name="step-functions-rest-api-integration-cdk-app"></a>

생성한 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\$1 ]

`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 테스트
<a name="step-functions-rest-api-integration-cdk-step-3"></a>

동기 Express 상태 시스템이 백엔드 통합으로 있는 API Gateway REST API를 만든 후 API Gateway를 테스트할 수 있습니다.

### API Gateway 콘솔을 사용하여 배포된 API Gateway 테스트하기
<a name="to-test-the-deployed-api-gateway-using-console"></a>

1. [Amazon API Gateway 콘솔을](https://console.aws.amazon.com/apigateway/) 열고 로그인합니다.

1. 이름이 `StepFunctionsRestApi`인 REST API를 선택합니다.

1. **리소스** 창에서 `ANY` 메서드를 선택합니다.

1. **테스트** 탭을 선택합니다. 탭을 표시하려면 오른쪽 화살표 버튼을 선택해야 할 수도 있습니다.

1. **Method(메서드)**에서 **POST**를 선택합니다.

1. **요청 본문**에서 다음 요청 파라미터를 복사합니다.

   ```
   {
       "key": "Hello"
   }
   ```

1. **테스트**를 선택합니다. 다음 정보가 표시됩니다.
   + **요청**은 메서드에 대해 호출된 리소스의 경로입니다.
   + **상태**는 응답의 HTTP 상태 코드입니다.
   + **지연 시간**은 호출자로부터 요청을 수신한 시간과 응답 반환 시간의 시간차입니다.
   + **응답 본문**은 HTTP 응답 본문입니다.
   + **응답 헤더**는 HTTP 응답 헤더입니다.
   + **로그**는 이 메서드가 API Gateway 콘솔 밖에서 호출되었을 경우 작성되었을 시뮬레이션된 Amazon CloudWatch Logs 입력입니다.
**참고**  
CloudWatch Logs 입력은 시뮬레이션된 것이지만 메서드 호출의 결과는 실제입니다.

**응답 본문** 출력은 다음과 같아야 합니다.

```
"Hello"
```

**작은 정보**  
다른 메서드와 잘못된 입력으로 API Gateway를 사용해 보고 오류 출력을 확인합니다. 특정 키를 찾도록 상태 시스템을 변경하고 테스트 중에 잘못된 키를 입력하면 상태 머신 실행이 실패하고 **응답 본문** 출력에 오류 메시지가 생성될 수 있습니다.

### cURL을 사용하여 배포된 API를 테스트하기
<a name="to-test-the-deployed-api-gateway-using-curl"></a>

1. 터미널 창을 엽니다.

1. 다음 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"
```

**작은 정보**  
다른 메서드와 잘못된 입력으로 API Gateway를 사용해 보고 오류 출력을 확인합니다. 특정 키를 찾도록 상태 시스템을 변경하고 테스트 중에 잘못된 키를 입력하면 상태 시스템 실행이 실패하고 **응답 본문** 출력에 오류 메시지가 생성될 수 있습니다.

## 4단계: 정리
<a name="step-functions-rest-api-integration-cdk-step-4"></a>

API Gateway 사용을 마치면 AWS CDK를 사용하여 상태 시스템과 API Gateway를 모두 제거할 수 있습니다. 앱의 기본 디렉토리에서 `cdk destroy`를 실행합니다.