๐ AWS CDK์ LocalStack์ ์ฌ์ฉํ ์์ ํ API REST ๋ง๋ค๊ธฐ: ์ฒ์๋ถํฐ ๋ก์ปฌ ํ๋ก๋์ ๊น์ง
Source: Dev.to
๐ ์๊ฐ
์ด ์ ์ฒด ํํ ๋ฆฌ์ผ์์๋ AWS CDK, TypeScript, LocalStack์ ์ฌ์ฉํด ์ฃผ๋ฌธ ๊ด๋ฆฌ์ฉ ๊ฐ๋ ฅํ REST API๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ๋๋ฆฝ๋๋ค. AWS๋ฅผ ์๋ฒฝํ ์๋ฎฌ๋ ์ด์ ํ๋ ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ค์ ํ๊ณ , ์ ์ฒด CRUD๋ฅผ ๊ตฌํํ๋ฉฐ, ์ฒ ์ ํ ํ ์คํธํ๋ ๊ณผ์ ์ ๋ฐฐ์ธ ์ ์์ต๋๋ค.
๐ฏ ๋ฌด์์ ๋ง๋ค ๊ฑด๊ฐ์?
- 5๊ฐ์ CRUD ์๋ํฌ์ธํธ๋ฅผ ๊ฐ์ถ ์์ ํ REST API
- ๊ฐ ์์ ์ ๋ด๋นํ๋ TypeScript Lambda ํจ์
- ์์์ฑ์ ์ํ DynamoDB ํ ์ด๋ธ
- ์ง์ ์ ์ญํ ์ ํ๋ API Gateway
- ๋น์ฉ ์์ด ๋ก์ปฌ์์ AWS๋ฅผ ์๋ฎฌ๋ ์ด์ ํ๋ LocalStack
- ์๋ํ ๋ฐ ์๋ ํ ์คํธ
๐ ๏ธ ๊ธฐ์ ์คํ
- AWS CDK v2.170.0 โ ์ธํ๋ผ์คํธ๋ญ์ฒ ์ฝ๋(IaC)
- TypeScript 5.x โ ์ฃผ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด
- Node.js 20+ โ ๋ฐํ์
- LocalStack โ ๋ก์ปฌ AWS ์๋ฎฌ๋ ์ด์
- DynamoDB โ NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค
- API Gateway โ API ๊ด๋ฆฌ
- Lambda โ ์๋ฒ๋ฆฌ์ค ํจ์
๐ง ์ด๊ธฐ ์ค์
1. VS Code์์ LocalStack ์ค์น
๐ฆ LocalStack ํ์ฅ ์ค์น
๋ฐฉ๋ฒ 1: VS Code Marketplace์์
- VS Code๋ฅผ ์ฝ๋๋ค.
- ํ์ฅ ํญ(
Ctrl+Shift+X๋๋Cmd+Shift+X)์ผ๋ก ์ด๋ํฉ๋๋ค. - **โLocalStackโ**์ ๊ฒ์ํฉ๋๋ค.
- LocalStack ๊ณต์ ํ์ฅ์ ์ค์นํฉ๋๋ค.
- VS Code๋ฅผ ์ฌ์์ํฉ๋๋ค.
๋ฐฉ๋ฒ 2: ๋ช ๋ น์ค์์
code --install-extension localstack.localstack
๋ฐฉ๋ฒ 3: ์๋ ์ค์น
VS Code Marketplace - LocalStack ํ์ด์ง์ ์ ์ํด โInstallโ ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
โ๏ธ ํ์ฅ ์ค์
์ค์ (Ctrl+, Windows, Cmd+, macOS)์ ์ด๊ณ **โLocalStackโ**์ ๊ฒ์ํ ๋ค ์๋ ์ต์
์ ์ถ๊ฐํฉ๋๋ค:
{
"localstack.endpoint": "http://localhost:4566",
"localstack.profile": "default",
"localstack.region": "us-east-1",
"localstack.autoStart": true,
"localstack.dockerFlags": "-d"
}
๐ฏ ํ์ฅ ๊ธฐ๋ฅ
- LocalStack ํจ๋: ์๋น์ค ์ํ, ์ค์๊ฐ ๋ก๊ทธ, ์๋น์ค ๊ด๋ฆฌ, ๋ฆฌ์์ค ํ์๊ธฐ.
- ์ฌ์ฉ ๊ฐ๋ฅํ ๋ช
๋ น (๋ช
๋ น ํ๋ ํธ
Ctrl+Shift+P):LocalStack: Startโ LocalStack ์์LocalStack: Stopโ LocalStack ์ค์งLocalStack: Restartโ LocalStack ์ฌ์์LocalStack: Show Logsโ ๋ก๊ทธ ๋ณด๊ธฐLocalStack: Open Web UIโ ์น UI ์ด๊ธฐ
- AWS CLI์ ํตํฉ: ์๋ํฌ์ธํธ ์๋ ์ค์ , ๋ก์ปฌ ํ๋กํ์ผ, AWS ๋ช ๋ น์ LocalStack์ผ๋ก ๋ผ์ฐํ .
๐ ํ์ฅ ์ค์น ํ์ธ
- ์ฌ์ด๋ ํจ๋: ์ฌ์ด๋๋ฐ์ LocalStack ์์ด์ฝ์ด ํ์๋ฉ๋๋ค.
- ๋ช
๋ น ํ๋ ํธ:
Ctrl+Shift+Pโ โLocalStackโ ๊ฒ์. - ์ํ ํ์์ค: ํ๋จ์ ์ํ ํ์๊ธฐ๊ฐ ๋ํ๋ฉ๋๋ค.
๐ ์ฒซ ์ฌ์ฉ
- LocalStack ํจ๋์ ์ฝ๋๋ค(์์ด์ฝ ํด๋ฆญ).
- Start LocalStack ๋ฒํผ์ด๋ ๋ช ๋ น์ ์ฌ์ฉํด LocalStack์ ์์ํฉ๋๋ค.
- ํจ๋์ Running์ด ํ์๋๋์ง ํ์ธํฉ๋๋ค.
- Logs ํญ์์ ๋ก๊ทธ๋ฅผ ํ์ธํฉ๋๋ค.
2. CDK ํ๋ก์ ํธ๋ฅผ ์ฒ์๋ถํฐ ๋ง๋ค๊ธฐ
๐ ์ฌ์ ์๊ตฌ์ฌํญ
๋ค์์ด ์ค์น๋์ด ์๋์ง ํ์ธํฉ๋๋ค:
# Node.js (๋ฒ์ 20 ์ด์)
node --version
# npm
npm --version
# AWS CDK CLI (์ ์ญ)
npm install -g aws-cdk
# CDK ์ค์น ํ์ธ
cdk --version
๐๏ธ CDK ํ๋ก์ ํธ ์ด๊ธฐํ
# ํ๋ก์ ํธ ๋๋ ํฐ๋ฆฌ ์์ฑ
mkdir cdk-api-localstask
cd cdk-api-localstask
# TypeScript๋ก CDK ํ๋ก์ ํธ ์ด๊ธฐํ
cdk init app --language typescript
์ด๊ธฐ ๊ตฌ์กฐ ํ์ธ
ls -la
# ๋ค์๊ณผ ๊ฐ์ ํ์ผ/๋๋ ํฐ๋ฆฌ๊ฐ ๋ณด์ฌ์ผ ํฉ๋๋ค:
# bin/ # ์ ํ๋ฆฌ์ผ์ด์
์ง์
์
# lib/ # ์คํ ์ ์
# test/ # ๋จ์ ํ
์คํธ
# package.json # ํ๋ก์ ํธ ์์กด์ฑ
# tsconfig.json # TypeScript ์ค์
# cdk.json # CDK ์ค์
์ถ๊ฐ ์์กด์ฑ ์ค์น
# LocalStack ๊ด๋ จ ์์กด์ฑ
npm install aws-cdk-local
# Lambda์ DynamoDB์ฉ ์์กด์ฑ
npm install @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb
# TypeScript์ฉ ์์กด์ฑ
npm install @types/aws-lambda @types/uuid uuid
# ๊ฐ๋ฐ์ฉ ์์กด์ฑ
npm install --save-dev @types/node typescript
โ๏ธ LocalStack ์คํฌ๋ฆฝํธ ์ค์
package.json์ ์ด์ด ๋ค์ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค:
{
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"synth": "cdk synth",
"deploy": "cdk deploy",
"local:synth": "npx cdklocal synth",
"local:deploy": "npx cdklocal deploy",
"local:destroy": "npx cdklocal destroy",
"local:diff": "npx cdklocal diff",
"local:bootstrap": "npx cdklocal bootstrap"
}
}
๐ง CDK๋ฅผ LocalStack์ ๋ง๊ฒ ์ค์
cdk.json (CDK ์ค์ ํ์ผ):
{
"app": "npx ts-node --prefer-ts-exts bin/app.ts",
"watch": {
"include": ["**"],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": false,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:disableStackTrace": false
}
}
๐ ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ ๋ง๋ค๊ธฐ
# ์ฝ๋ ์ ๋ฆฌ๋ฅผ ์ํ ๋๋ ํฐ๋ฆฌ ์์ฑ
mkdir -p lib/lambdas
mkdir -p lib/types
# ๊ธฐ๋ณธ ํ์ผ ์์ฑ
touch lib/types/order.ts
touch lib/lambdas/create-order.ts
touch lib/lambdas/get-order.ts
touch lib/lambdas/list-orders.ts
touch lib/lambdas/update-order.ts
touch lib/lambdas/delete-order.ts
๐ฏ ๋ฉ์ธ ์คํ ์ค์
bin/app.ts (์ ํ๋ฆฌ์ผ์ด์
์ง์
์ ):
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkApiLocalstackStack } from '../lib/cdk-api-localstask-stack';
const app = new cdk.App();
new CdkApiLocalstackStack(app, 'CdkApiLocalstackStack', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT || '000000000000', // LocalStack ๊ธฐ๋ณธ๊ฐ
region: process.env.CDK_DEFAULT_REGION || 'us-east-1',
},
});