## 주요 변경사항 ### 신규 기능 - POST /recommend: 기술 스택 기반 인스턴스 추천 API - 아시아 리전 필터링 (Seoul, Tokyo, Osaka, Singapore) - 매칭 점수 알고리즘 (메모리 40%, vCPU 30%, 가격 20%, 스토리지 10%) ### 보안 강화 (Security 9.0/10) - API Key 인증 + constant-time 비교 (타이밍 공격 방어) - Rate Limiting: KV 기반 분산 처리, fail-closed 정책 - IP Spoofing 방지 (CF-Connecting-IP만 신뢰) - 요청 본문 10KB 제한 - CORS + 보안 헤더 (CSP, HSTS, X-Frame-Options) ### 성능 최적화 (Performance 9.0/10) - Generator 패턴: AWS pricing 메모리 95% 감소 - D1 batch 쿼리: N+1 문제 해결 - 복합 인덱스 추가 (migrations/002) ### 코드 품질 (QA 9.0/10) - 127개 테스트 (vitest) - 구조화된 로깅 (민감정보 마스킹) - 상수 중앙화 (constants.ts) - 입력 검증 유틸리티 (utils/validation.ts) ### Vultr 연동 수정 - relay 서버 헤더: Authorization: Bearer → X-API-Key Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
691 lines
16 KiB
Markdown
691 lines
16 KiB
Markdown
# Cloud Instances API Documentation
|
||
|
||
## 개요
|
||
|
||
클라우드 인스턴스 가격 비교 및 기술 스택 기반 추천 API
|
||
|
||
- **Base URL**: `https://cloud-instances-api.kappa-d8e.workers.dev`
|
||
- **인증**: `X-API-Key` 헤더 필수
|
||
- **Providers**: Linode, Vultr, AWS
|
||
- **지원 리전**: 아시아 (서울, 도쿄, 오사카, 싱가포르, 홍콩)
|
||
|
||
---
|
||
|
||
## 인증
|
||
|
||
모든 API 요청에 `X-API-Key` 헤더 필요:
|
||
|
||
```http
|
||
X-API-Key: your-api-key
|
||
```
|
||
|
||
인증 실패 시:
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "UNAUTHORIZED",
|
||
"message": "API key is missing or invalid"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 엔드포인트
|
||
|
||
### 1. Health Check
|
||
|
||
시스템 상태 및 provider 동기화 상태 확인
|
||
|
||
**Request**
|
||
```http
|
||
GET /health
|
||
```
|
||
|
||
**Response**
|
||
```json
|
||
{
|
||
"status": "healthy",
|
||
"timestamp": "2025-01-22T10:00:00.000Z",
|
||
"components": {
|
||
"database": {
|
||
"status": "healthy",
|
||
"latency_ms": 12
|
||
},
|
||
"providers": [
|
||
{
|
||
"name": "linode",
|
||
"status": "healthy",
|
||
"last_sync": "2025-01-22 09:30:00",
|
||
"sync_status": "success",
|
||
"regions_count": 11,
|
||
"instances_count": 45
|
||
},
|
||
{
|
||
"name": "vultr",
|
||
"status": "healthy",
|
||
"last_sync": "2025-01-22 09:28:00",
|
||
"sync_status": "success",
|
||
"regions_count": 8,
|
||
"instances_count": 32
|
||
},
|
||
{
|
||
"name": "aws",
|
||
"status": "degraded",
|
||
"last_sync": "2025-01-21 15:00:00",
|
||
"sync_status": "success",
|
||
"regions_count": 15,
|
||
"instances_count": 120,
|
||
"error": "Sync delayed"
|
||
}
|
||
]
|
||
},
|
||
"summary": {
|
||
"total_providers": 3,
|
||
"healthy_providers": 2,
|
||
"total_regions": 34,
|
||
"total_instances": 197
|
||
}
|
||
}
|
||
```
|
||
|
||
**상태 코드**
|
||
- `200`: 시스템 정상 (all components healthy)
|
||
- `503`: 시스템 문제 (degraded or unhealthy)
|
||
|
||
**Health Status**
|
||
- `healthy`: 정상 작동 (최근 24시간 이내 동기화)
|
||
- `degraded`: 부분 문제 (24-48시간 이내 동기화 또는 일부 에러)
|
||
- `unhealthy`: 심각한 문제 (48시간 이상 미동기화 또는 데이터베이스 연결 실패)
|
||
|
||
---
|
||
|
||
### 2. 인스턴스 목록 조회
|
||
|
||
조건에 맞는 인스턴스 조회 (필터링, 정렬, 페이지네이션 지원)
|
||
|
||
**Request**
|
||
```http
|
||
GET /instances?provider=linode&min_vcpu=2&max_price=50&sort_by=price&order=asc&limit=20
|
||
```
|
||
|
||
**Query Parameters**
|
||
|
||
| 파라미터 | 타입 | 필수 | 설명 | 기본값 |
|
||
|---------|------|------|------|--------|
|
||
| `provider` | string | ❌ | Provider 필터 (`linode`, `vultr`, `aws`) | - |
|
||
| `region` | string | ❌ | 리전 코드 필터 (예: `ap-northeast-1`) | - |
|
||
| `min_vcpu` | integer | ❌ | 최소 vCPU 수 | - |
|
||
| `max_vcpu` | integer | ❌ | 최대 vCPU 수 | - |
|
||
| `min_memory_gb` | number | ❌ | 최소 메모리 (GB) | - |
|
||
| `max_memory_gb` | number | ❌ | 최대 메모리 (GB) | - |
|
||
| `max_price` | number | ❌ | 최대 월 가격 (USD) | - |
|
||
| `instance_family` | string | ❌ | 인스턴스 패밀리 (`general`, `compute`, `memory`, `storage`, `gpu`) | - |
|
||
| `has_gpu` | boolean | ❌ | GPU 인스턴스 필터 (`true`, `false`) | - |
|
||
| `sort_by` | string | ❌ | 정렬 필드 (아래 참조) | - |
|
||
| `order` | string | ❌ | 정렬 순서 (`asc`, `desc`) | `asc` |
|
||
| `limit` | integer | ❌ | 결과 개수 (1-100) | 50 |
|
||
| `offset` | integer | ❌ | 결과 오프셋 (페이지네이션) | 0 |
|
||
|
||
**유효한 정렬 필드**
|
||
- `price` / `monthly_price` / `hourly_price`
|
||
- `vcpu`
|
||
- `memory_mb` / `memory_gb`
|
||
- `storage_gb`
|
||
- `instance_name`
|
||
- `provider`
|
||
- `region`
|
||
|
||
**Response**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"instances": [
|
||
{
|
||
"id": 123,
|
||
"instance_id": "g6-standard-2",
|
||
"instance_name": "Linode 4GB",
|
||
"vcpu": 2,
|
||
"memory_mb": 4096,
|
||
"storage_gb": 80,
|
||
"transfer_tb": 4,
|
||
"network_speed_gbps": 4,
|
||
"gpu_count": 0,
|
||
"gpu_type": null,
|
||
"instance_family": "general",
|
||
"provider": {
|
||
"id": 1,
|
||
"name": "linode",
|
||
"display_name": "Linode"
|
||
},
|
||
"region": {
|
||
"id": 5,
|
||
"region_code": "ap-northeast",
|
||
"region_name": "Tokyo (jp-tyo-3)",
|
||
"country_code": "JP"
|
||
},
|
||
"pricing": {
|
||
"hourly_price": 0.036,
|
||
"monthly_price": 24.0,
|
||
"currency": "USD",
|
||
"available": 1
|
||
}
|
||
}
|
||
],
|
||
"pagination": {
|
||
"total": 45,
|
||
"limit": 20,
|
||
"offset": 0,
|
||
"has_more": true
|
||
},
|
||
"metadata": {
|
||
"cached": false,
|
||
"last_sync": "2025-01-22T10:00:00.000Z",
|
||
"query_time_ms": 45,
|
||
"filters_applied": {
|
||
"provider": "linode",
|
||
"min_vcpu": 2,
|
||
"max_price": 50
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**상태 코드**
|
||
- `200`: 성공
|
||
- `400`: 잘못된 파라미터
|
||
- `500`: 서버 에러
|
||
|
||
**캐시 동작**
|
||
- TTL: 5분 (300초)
|
||
- 캐시 히트 시 `metadata.cached: true`
|
||
- 캐시 헤더: `Cache-Control: public, max-age=300`
|
||
|
||
---
|
||
|
||
### 3. 데이터 동기화
|
||
|
||
Provider API에서 최신 데이터 가져오기
|
||
|
||
**Request**
|
||
```http
|
||
POST /sync
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"providers": ["linode", "vultr", "aws"],
|
||
"force": false
|
||
}
|
||
```
|
||
|
||
**Request Body**
|
||
|
||
| 필드 | 타입 | 필수 | 설명 | 기본값 |
|
||
|------|------|------|------|--------|
|
||
| `providers` | string[] | ❌ | 동기화할 provider 목록 | `["linode"]` |
|
||
| `force` | boolean | ❌ | 강제 동기화 여부 (사용되지 않음) | `false` |
|
||
|
||
**Response**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"sync_id": "sync_1737545678901_abc123def",
|
||
"success": true,
|
||
"started_at": "2025-01-22T10:00:00.000Z",
|
||
"completed_at": "2025-01-22T10:02:15.000Z",
|
||
"total_duration_ms": 135000,
|
||
"providers": [
|
||
{
|
||
"provider": "linode",
|
||
"success": true,
|
||
"regions_synced": 11,
|
||
"instances_synced": 45,
|
||
"pricing_synced": 495,
|
||
"duration_ms": 45000
|
||
},
|
||
{
|
||
"provider": "vultr",
|
||
"success": true,
|
||
"regions_synced": 8,
|
||
"instances_synced": 32,
|
||
"pricing_synced": 256,
|
||
"duration_ms": 38000
|
||
},
|
||
{
|
||
"provider": "aws",
|
||
"success": false,
|
||
"regions_synced": 0,
|
||
"instances_synced": 0,
|
||
"pricing_synced": 0,
|
||
"duration_ms": 52000,
|
||
"error": "API authentication failed",
|
||
"error_details": {
|
||
"code": "CREDENTIALS_ERROR",
|
||
"message": "Invalid AWS credentials"
|
||
}
|
||
}
|
||
],
|
||
"summary": {
|
||
"total_providers": 3,
|
||
"successful_providers": 2,
|
||
"failed_providers": 1,
|
||
"total_regions": 19,
|
||
"total_instances": 77,
|
||
"total_pricing": 751
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**상태 코드**
|
||
- `200`: 동기화 완료 (일부 실패 포함)
|
||
- `400`: 잘못된 요청 (잘못된 provider 이름 등)
|
||
- `500`: 서버 에러
|
||
|
||
**에러 케이스**
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "UNSUPPORTED_PROVIDERS",
|
||
"message": "Unsupported providers: digitalocean",
|
||
"details": {
|
||
"unsupported": ["digitalocean"],
|
||
"supported": ["linode", "vultr", "aws"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 기술 스택 기반 인스턴스 추천
|
||
|
||
기술 스택과 규모에 맞는 최적 인스턴스 추천
|
||
|
||
**Request**
|
||
```http
|
||
POST /recommend
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"stack": ["nginx", "php-fpm", "mysql"],
|
||
"scale": "medium",
|
||
"budget_max": 50
|
||
}
|
||
```
|
||
|
||
**Request Body**
|
||
|
||
| 필드 | 타입 | 필수 | 설명 |
|
||
|------|------|------|------|
|
||
| `stack` | string[] | ✅ | 기술 스택 목록 (아래 참조) |
|
||
| `scale` | string | ✅ | 배포 규모 (`small`, `medium`, `large`) |
|
||
| `budget_max` | number | ❌ | 월 최대 예산 (USD) |
|
||
|
||
**지원 기술 스택**
|
||
|
||
| 스택 | 최소 메모리 | 권장 메모리 |
|
||
|------|------------|------------|
|
||
| `nginx` | 128 MB | 256 MB |
|
||
| `php-fpm` | 512 MB | 1 GB |
|
||
| `mysql` | 1 GB | 2 GB |
|
||
| `mariadb` | 1 GB | 2 GB |
|
||
| `postgresql` | 1 GB | 2 GB |
|
||
| `redis` | 256 MB | 512 MB |
|
||
| `elasticsearch` | 2 GB | 4 GB |
|
||
| `nodejs` | 512 MB | 1 GB |
|
||
| `docker` | 1 GB | 2 GB |
|
||
| `mongodb` | 1 GB | 2 GB |
|
||
|
||
**스케일별 리소스 계산**
|
||
|
||
| 스케일 | 메모리 계산 | vCPU 계산 |
|
||
|--------|------------|-----------|
|
||
| `small` | 최소 사양 | 메모리 기반 (2GB당 1 vCPU) |
|
||
| `medium` | 권장 사양 | 메모리 기반 (2GB당 1 vCPU) |
|
||
| `large` | 권장 × 1.5배 | 메모리 기반 (2GB당 1 vCPU) |
|
||
|
||
- OS 오버헤드: **768 MB** (모든 스케일 공통)
|
||
- 최소 vCPU: **1개**
|
||
|
||
**Response**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"requirements": {
|
||
"min_memory_mb": 4096,
|
||
"min_vcpu": 2,
|
||
"breakdown": {
|
||
"nginx": "256MB",
|
||
"php-fpm": "1GB",
|
||
"mysql": "2GB",
|
||
"os_overhead": "768MB"
|
||
}
|
||
},
|
||
"recommendations": [
|
||
{
|
||
"rank": 1,
|
||
"provider": "linode",
|
||
"instance": "Linode 4GB",
|
||
"region": "Tokyo (jp-tyo-3)",
|
||
"specs": {
|
||
"vcpu": 2,
|
||
"memory_mb": 4096,
|
||
"storage_gb": 80
|
||
},
|
||
"price": {
|
||
"monthly": 24.0,
|
||
"hourly": 0.036
|
||
},
|
||
"match_score": 95,
|
||
"pros": [
|
||
"메모리 최적 적합",
|
||
"vCPU 적합",
|
||
"스토리지 80GB 포함"
|
||
],
|
||
"cons": []
|
||
},
|
||
{
|
||
"rank": 2,
|
||
"provider": "vultr",
|
||
"instance": "4GB Memory",
|
||
"region": "Seoul (icn)",
|
||
"specs": {
|
||
"vcpu": 2,
|
||
"memory_mb": 4096,
|
||
"storage_gb": 80
|
||
},
|
||
"price": {
|
||
"monthly": 24.0,
|
||
"hourly": 0.036
|
||
},
|
||
"match_score": 95,
|
||
"pros": [
|
||
"메모리 최적 적합",
|
||
"vCPU 적합",
|
||
"스토리지 80GB 포함"
|
||
],
|
||
"cons": []
|
||
},
|
||
{
|
||
"rank": 3,
|
||
"provider": "linode",
|
||
"instance": "Linode 8GB",
|
||
"region": "Tokyo (jp-tyo-3)",
|
||
"specs": {
|
||
"vcpu": 4,
|
||
"memory_mb": 8192,
|
||
"storage_gb": 160
|
||
},
|
||
"price": {
|
||
"monthly": 48.0,
|
||
"hourly": 0.072
|
||
},
|
||
"match_score": 75,
|
||
"pros": [
|
||
"vCPU 여유 (4 cores)",
|
||
"메모리 충분 (8GB)",
|
||
"스토리지 160GB 포함"
|
||
],
|
||
"cons": [
|
||
"예산 초과 ($48 > $50)"
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"meta": {
|
||
"query_time_ms": 85
|
||
}
|
||
}
|
||
```
|
||
|
||
**매칭 스코어 계산**
|
||
|
||
| 조건 | 점수 |
|
||
|------|------|
|
||
| 메모리 정확히 일치 | 100점 |
|
||
| 메모리 20% 초과 | 90점 |
|
||
| 메모리 50% 초과 | 70점 |
|
||
| 메모리 부족 | 0점 (제외) |
|
||
| vCPU 일치 | +0점 |
|
||
| vCPU 부족 | -10점 |
|
||
| 예산 초과 | -20점 |
|
||
|
||
**상태 코드**
|
||
- `200`: 성공
|
||
- `400`: 잘못된 요청
|
||
- `500`: 서버 에러
|
||
|
||
**에러 케이스**
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "INVALID_STACK",
|
||
"message": "Unsupported stacks: mongodb-atlas",
|
||
"details": {
|
||
"invalid": ["mongodb-atlas"],
|
||
"supported": [
|
||
"nginx", "php-fpm", "mysql", "mariadb",
|
||
"postgresql", "redis", "elasticsearch",
|
||
"nodejs", "docker", "mongodb"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 아시아 리전 목록
|
||
|
||
### Linode
|
||
- `ap-northeast` - Tokyo (jp-tyo-3)
|
||
- `ap-south` - Osaka (jp-osa-1)
|
||
- `ap-southeast` - Singapore (sg-sin-1)
|
||
|
||
### Vultr
|
||
- `icn` - Seoul
|
||
- `nrt` - Tokyo
|
||
- `itm` - Osaka
|
||
|
||
### AWS
|
||
- `ap-northeast-1` - Tokyo
|
||
- `ap-northeast-2` - Seoul
|
||
- `ap-northeast-3` - Osaka
|
||
- `ap-southeast-1` - Singapore
|
||
- `ap-east-1` - Hong Kong
|
||
|
||
---
|
||
|
||
## 에러 응답 형식
|
||
|
||
모든 에러는 아래 형식으로 응답:
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "ERROR_CODE",
|
||
"message": "Human readable error message",
|
||
"details": {
|
||
"additional": "error details"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**주요 에러 코드**
|
||
|
||
| 코드 | 설명 | 상태 코드 |
|
||
|------|------|----------|
|
||
| `UNAUTHORIZED` | 인증 실패 | 401 |
|
||
| `INVALID_PARAMETER` | 잘못된 파라미터 | 400 |
|
||
| `MISSING_PARAMETER` | 필수 파라미터 누락 | 400 |
|
||
| `INVALID_CONTENT_TYPE` | Content-Type이 application/json이 아님 | 400 |
|
||
| `INVALID_JSON` | JSON 파싱 실패 | 400 |
|
||
| `INVALID_STACK` | 지원하지 않는 기술 스택 | 400 |
|
||
| `EMPTY_STACK` | 스택 배열이 비어 있음 | 400 |
|
||
| `UNSUPPORTED_PROVIDERS` | 지원하지 않는 provider | 400 |
|
||
| `QUERY_FAILED` | 쿼리 실행 실패 | 500 |
|
||
| `INTERNAL_ERROR` | 서버 내부 에러 | 500 |
|
||
| `SYNC_FAILED` | 동기화 작업 실패 | 500 |
|
||
|
||
---
|
||
|
||
## Rate Limiting
|
||
|
||
| 엔드포인트 | 제한 |
|
||
|-----------|------|
|
||
| `/health` | 제한 없음 |
|
||
| `/instances` | 100 req/min |
|
||
| `/sync` | 10 req/min |
|
||
| `/recommend` | 60 req/min |
|
||
|
||
Rate limit 초과 시:
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "RATE_LIMIT_EXCEEDED",
|
||
"message": "Too many requests. Please try again later.",
|
||
"details": {
|
||
"limit": 60,
|
||
"window": "1 minute",
|
||
"retry_after": 45
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 사용 예시
|
||
|
||
### 1. 워드프레스 서버 추천
|
||
|
||
```bash
|
||
curl -X POST "https://cloud-instances-api.kappa-d8e.workers.dev/recommend" \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-API-Key: YOUR_API_KEY" \
|
||
-d '{
|
||
"stack": ["nginx", "php-fpm", "mysql"],
|
||
"scale": "medium"
|
||
}'
|
||
```
|
||
|
||
**예상 요구사항**
|
||
- 메모리: 4 GB (nginx 256MB + php-fpm 1GB + mysql 2GB + OS 768MB)
|
||
- vCPU: 2 cores
|
||
|
||
---
|
||
|
||
### 2. Node.js 앱 (예산 제한 있음)
|
||
|
||
```bash
|
||
curl -X POST "https://cloud-instances-api.kappa-d8e.workers.dev/recommend" \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-API-Key: YOUR_API_KEY" \
|
||
-d '{
|
||
"stack": ["nginx", "nodejs", "redis"],
|
||
"scale": "small",
|
||
"budget_max": 20
|
||
}'
|
||
```
|
||
|
||
**예상 요구사항**
|
||
- 메모리: 1.6 GB (nginx 128MB + nodejs 512MB + redis 256MB + OS 768MB)
|
||
- vCPU: 1 core
|
||
- 예산: $20 이하
|
||
|
||
---
|
||
|
||
### 3. 대규모 전자상거래 플랫폼
|
||
|
||
```bash
|
||
curl -X POST "https://cloud-instances-api.kappa-d8e.workers.dev/recommend" \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-API-Key: YOUR_API_KEY" \
|
||
-d '{
|
||
"stack": ["nginx", "nodejs", "postgresql", "redis", "elasticsearch"],
|
||
"scale": "large"
|
||
}'
|
||
```
|
||
|
||
**예상 요구사항**
|
||
- 메모리: 13.5 GB (nginx 384MB + nodejs 1.5GB + postgresql 3GB + redis 768MB + elasticsearch 6GB + OS 768MB)
|
||
- vCPU: 7 cores
|
||
|
||
---
|
||
|
||
### 4. Provider별 가격 비교
|
||
|
||
```bash
|
||
# Linode만 조회
|
||
curl -X GET "https://cloud-instances-api.kappa-d8e.workers.dev/instances?provider=linode&min_vcpu=2&max_price=30&sort_by=price&order=asc&limit=10" \
|
||
-H "X-API-Key: YOUR_API_KEY"
|
||
|
||
# Vultr만 조회
|
||
curl -X GET "https://cloud-instances-api.kappa-d8e.workers.dev/instances?provider=vultr&min_vcpu=2&max_price=30&sort_by=price&order=asc&limit=10" \
|
||
-H "X-API-Key: YOUR_API_KEY"
|
||
|
||
# 모든 provider 조회 (가격 순 정렬)
|
||
curl -X GET "https://cloud-instances-api.kappa-d8e.workers.dev/instances?min_vcpu=2&max_price=30&sort_by=price&order=asc&limit=30" \
|
||
-H "X-API-Key: YOUR_API_KEY"
|
||
```
|
||
|
||
---
|
||
|
||
### 5. 특정 리전에서 GPU 인스턴스 검색
|
||
|
||
```bash
|
||
curl -X GET "https://cloud-instances-api.kappa-d8e.workers.dev/instances?region=ap-northeast-1&has_gpu=true&sort_by=price&order=asc" \
|
||
-H "X-API-Key: YOUR_API_KEY"
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 메모리 최적화 인스턴스 검색
|
||
|
||
```bash
|
||
curl -X GET "https://cloud-instances-api.kappa-d8e.workers.dev/instances?instance_family=memory&min_memory_gb=16&sort_by=price&order=asc" \
|
||
-H "X-API-Key: YOUR_API_KEY"
|
||
```
|
||
|
||
---
|
||
|
||
## 버전 정보
|
||
|
||
- **API Version**: 1.0.0
|
||
- **Last Updated**: 2025-01-22
|
||
- **Runtime**: Cloudflare Workers
|
||
- **Database**: Cloudflare D1 (SQLite)
|
||
|
||
---
|
||
|
||
## 지원 및 문의
|
||
|
||
- **GitHub**: https://github.com/your-org/cloud-instances-api
|
||
- **Email**: support@example.com
|
||
- **Documentation**: https://docs.example.com
|
||
|
||
---
|
||
|
||
## 변경 이력
|
||
|
||
### v1.0.0 (2025-01-22)
|
||
- ✅ 초기 릴리즈
|
||
- ✅ `/health` 엔드포인트 구현
|
||
- ✅ `/instances` 엔드포인트 구현 (필터링, 정렬, 페이지네이션)
|
||
- ✅ `/sync` 엔드포인트 구현 (Linode, Vultr, AWS)
|
||
- ✅ `/recommend` 엔드포인트 구현 (기술 스택 기반 추천)
|
||
- ✅ 캐시 시스템 구현 (5분 TTL)
|
||
- ✅ 아시아 리전 지원
|
||
- ✅ Rate limiting 구현
|