Skip to content

Latest commit

Β 

History

History
591 lines (438 loc) Β· 12.1 KB

File metadata and controls

591 lines (438 loc) Β· 12.1 KB

πŸ“‘ API λͺ…μ„Έμ„œ

Flow λŒ€κΈ°μ—΄ μ‹œμŠ€ν…œμ˜ 전체 REST API λ¬Έμ„œ

Base URL: http://localhost:9010


πŸ“‘ λͺ©μ°¨

  1. λŒ€κΈ°μ—΄ 관리 API
  2. 쑰회 API
  3. 톡계 및 이λ ₯ API
  4. μ›Ή νŽ˜μ΄μ§€ API
  5. μ—λŸ¬ μ½”λ“œ

🎫 λŒ€κΈ°μ—΄ 관리 API

1. λŒ€κΈ°μ—΄ 등둝

μ‚¬μš©μžλ₯Ό λŒ€κΈ°μ—΄μ— λ“±λ‘ν•˜κ³  ν˜„μž¬ μˆœμœ„λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

Endpoint

POST /api/v1/queue

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름 (λ©€ν‹° 큐 지원)
user_id Long βœ… - μ‚¬μš©μž ID (μ–‘μˆ˜)
is_vip Boolean ❌ false VIP μ—¬λΆ€ (trueλ©΄ μš°μ„ μˆœμœ„)

Request Example

# 일반 μ‚¬μš©μž 등둝
curl -X POST "http://localhost:9010/api/v1/queue?user_id=100&queue=default"

# VIP μ‚¬μš©μž 등둝
curl -X POST "http://localhost:9010/api/v1/queue?user_id=101&queue=default&is_vip=true"

Response (200 OK)

{
  "rank": 1
}

Error Response (400 Bad Request)

{
  "code": "UQ-001",
  "reason": "이미 λ“±λ‘λœ μ‚¬μš©μžμž…λ‹ˆλ‹€."
}
{
  "code": "UQ-005",
  "reason": "λŒ€κΈ°μ—΄μ΄ 가득 μ°ΌμŠ΅λ‹ˆλ‹€. μ΅œλŒ€ μš©λŸ‰: 100λͺ…"
}

μ„€λͺ…

  • 등둝 성곡 μ‹œ ν˜„μž¬ μˆœμœ„λ₯Ό μ¦‰μ‹œ λ°˜ν™˜
  • VIP μ‚¬μš©μžλŠ” 일반 μ‚¬μš©μžλ³΄λ‹€ 항상 μ•ž μˆœμœ„
  • 동일 λ“±κΈ‰ λ‚΄μ—μ„œλŠ” μ„ μ°©μˆœ (νƒ€μž„μŠ€νƒ¬ν”„ κΈ°μ€€)
  • 쀑볡 등둝 μ‹œ μ—λŸ¬ λ°˜ν™˜

2. μ§„μž… ν—ˆμš© (κ΄€λ¦¬μž)

λŒ€κΈ°μ—΄μ—μ„œ Nλͺ…μ˜ μ‚¬μš©μžλ₯Ό μ§„μž… ν—ˆμš© μƒνƒœλ‘œ λ³€κ²½ν•©λ‹ˆλ‹€.

Endpoint

POST /api/v1/queue/allow

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름
count Long βœ… - μ§„μž… ν—ˆμš©ν•  μ‚¬μš©μž 수

Request Example

# 10λͺ… μ§„μž… ν—ˆμš©
curl -X POST "http://localhost:9010/api/v1/queue/allow?queue=default&count=10"

Response (200 OK)

{
  "requestCount": 10,
  "allowedCount": 10
}

μ„€λͺ…

  • λŒ€κΈ°μ—΄ μ•žμ—μ„œλΆ€ν„° μˆœμ„œλŒ€λ‘œ μ§„μž… ν—ˆμš©
  • μ§„μž… ν—ˆμš©λœ μ‚¬μš©μžλŠ” proceed 큐둜 이동
  • requestCount와 allowedCountκ°€ λ‹€λ₯Ό 수 있음 (λŒ€κΈ°μžκ°€ λΆ€μ‘±ν•œ 경우)

πŸ” 쑰회 API

3. μˆœμœ„ 쑰회

μ‚¬μš©μžμ˜ ν˜„μž¬ λŒ€κΈ° μˆœμœ„λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.

Endpoint

GET /api/v1/queue/rank

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름
user_id Long βœ… - μ‚¬μš©μž ID

Request Example

curl "http://localhost:9010/api/v1/queue/rank?user_id=100&queue=default"

Response (200 OK)

{
  "rank": 5
}

μ„€λͺ…

  • rank 값이 -1이면 λŒ€κΈ°μ—΄μ— μ—†λŠ” μ‚¬μš©μž
  • μˆœμœ„λŠ” 1λΆ€ν„° μ‹œμž‘ (1 = κ°€μž₯ μ•ž)

4. μ§„μž… μ—¬λΆ€ 확인

μ‚¬μš©μžκ°€ μ§„μž… ν—ˆμš©λ˜μ—ˆλŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.

Endpoint

GET /api/v1/queue/allowed

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름
user_id Long βœ… - μ‚¬μš©μž ID

Request Example

curl "http://localhost:9010/api/v1/queue/allowed?user_id=100&queue=default"

Response (200 OK)

{
  "allowed": true
}
{
  "allowed": false
}

μ„€λͺ…

  • allowed: true: μ§„μž… ν—ˆμš©λ¨, μ„œλΉ„μŠ€ 이용 κ°€λŠ₯
  • allowed: false: 아직 λŒ€κΈ° 쀑

5. 토큰 생성

μ‚¬μš©μžμ˜ μ§„μž… 토큰을 μƒμ„±ν•˜κ³  쿠킀에 μ €μž₯ν•©λ‹ˆλ‹€.

Endpoint

GET /api/v1/queue/touch

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름
user_id Long βœ… - μ‚¬μš©μž ID

Request Example

curl "http://localhost:9010/api/v1/queue/touch?user_id=100&queue=default"

Response (200 OK)

a3b5c7d9e1f2a4b6c8d0e2f4a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b4c6

Response Headers

Set-Cookie: user-queue-default-token=a3b5c7d9...; Max-Age=300; Path=/

μ„€λͺ…

  • SHA-256 ν•΄μ‹œ 기반 토큰 생성
  • μΏ ν‚€λ‘œ μžλ™ μ €μž₯ (유효 μ‹œκ°„: 300초)
  • μ§„μž… μ‹œ 토큰 검증에 μ‚¬μš©

πŸ“Š 톡계 및 이λ ₯ API

6. λŒ€κΈ°μ—΄ 톡계 쑰회

λŒ€κΈ° 쀑인 μ‚¬μš©μž μˆ˜μ™€ μ§„μž… ν—ˆμš©λœ μ‚¬μš©μž 수λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.

Endpoint

GET /api/v1/queue/statistics

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름

Request Example

curl "http://localhost:9010/api/v1/queue/statistics?queue=default"

Response (200 OK)

{
  "queue": "default",
  "waitingCount": 150,
  "allowedCount": 50
}

μ„€λͺ…

  • waitingCount: ν˜„μž¬ λŒ€κΈ° 쀑인 μ‚¬μš©μž 수
  • allowedCount: μ§„μž… ν—ˆμš©λœ μ‚¬μš©μž 수
  • μ‹€μ‹œκ°„ 톡계 제곡

7. μ‚¬μš©μž 이λ ₯ 쑰회

νŠΉμ • μ‚¬μš©μžμ˜ λŒ€κΈ°μ—΄ 이λ ₯을 μ‘°νšŒν•©λ‹ˆλ‹€.

Endpoint

GET /api/v1/queue/history

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름
user_id Long βœ… - μ‚¬μš©μž ID
count Integer ❌ 10 μ‘°νšŒν•  이λ ₯ 개수

Request Example

curl "http://localhost:9010/api/v1/queue/history?user_id=100&queue=default&count=5"

Response (200 OK)

[
  {
    "queue": "default",
    "userId": 100,
    "action": "ALLOW",
    "timestamp": 1730000016
  },
  {
    "queue": "default",
    "userId": 100,
    "action": "REGISTER",
    "timestamp": 1730000000
  }
]

μ„€λͺ…

  • μ΅œμ‹  이λ ₯λΆ€ν„° λ°˜ν™˜ (μ‹œκ°„ μ—­μˆœ)
  • action: REGISTER (등둝), ALLOW (μ§„μž… ν—ˆμš©)
  • timestamp: Unix timestamp (초 λ‹¨μœ„)

8. 전체 λŒ€κΈ°μ—΄ 이λ ₯ 쑰회

큐의 전체 이λ ₯을 μ‘°νšŒν•©λ‹ˆλ‹€ (κ΄€λ¦¬μžμš©).

Endpoint

GET /api/v1/queue/history/all

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름
count Integer ❌ 50 μ‘°νšŒν•  이λ ₯ 개수

Request Example

curl "http://localhost:9010/api/v1/queue/history/all?queue=default&count=20"

Response (200 OK)

[
  {
    "queue": "default",
    "userId": 102,
    "action": "ALLOW",
    "timestamp": 1730000020
  },
  {
    "queue": "default",
    "userId": 101,
    "action": "ALLOW",
    "timestamp": 1730000016
  },
  {
    "queue": "default",
    "userId": 100,
    "action": "REGISTER",
    "timestamp": 1730000000
  }
]

μ„€λͺ…

  • λͺ¨λ“  μ‚¬μš©μžμ˜ 이λ ₯ 포함
  • μ΅œμ‹  이λ ₯λΆ€ν„° λ°˜ν™˜
  • 감사 및 λͺ¨λ‹ˆν„°λ§ λͺ©μ 

🎨 μ›Ή νŽ˜μ΄μ§€ API

9. λŒ€κΈ°μ‹€ μ›Ή νŽ˜μ΄μ§€

μ‚¬μš©μž μΉœν™”μ μΈ λŒ€κΈ°μ‹€ UIλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

Endpoint

GET /waiting-room

Query Parameters

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
queue String ❌ "default" 큐 이름
user_id Long βœ… - μ‚¬μš©μž ID

Request Example

http://localhost:9010/waiting-room?queue=default&user_id=100

Response

  • HTML νŽ˜μ΄μ§€ (Thymeleaf ν…œν”Œλ¦Ώ)
  • μ‹€μ‹œκ°„ μˆœμœ„ μ—…λ°μ΄νŠΈ (폴링 방식)
  • μ§„μž… ν—ˆμš© μ‹œ μžλ™ λ¦¬λ‹€μ΄λ ‰νŠΈ

UI κΈ°λŠ₯

  • ν˜„μž¬ μˆœμœ„ ν‘œμ‹œ
  • λŒ€κΈ° 쀑인 μ‚¬μš©μž 수
  • μ˜ˆμƒ λŒ€κΈ° μ‹œκ°„ (계산)
  • μžλ™ μƒˆλ‘œκ³ μΉ¨

❌ μ—λŸ¬ μ½”λ“œ

HTTP μƒνƒœ μ½”λ“œ

μƒνƒœ μ½”λ“œ μ„€λͺ…
200 OK μš”μ²­ 성곡
400 Bad Request 잘λͺ»λœ μš”μ²­ (검증 μ‹€νŒ¨, 쀑볡 등둝)
404 Not Found λ¦¬μ†ŒμŠ€λ₯Ό 찾을 수 μ—†μŒ
500 Internal Server Error μ„œλ²„ λ‚΄λΆ€ 였λ₯˜

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ—λŸ¬ μ½”λ“œ

μ½”λ“œ HTTP μƒνƒœ μ„€λͺ… 원인
UQ-001 400 이미 λ“±λ‘λœ μ‚¬μš©μžμž…λ‹ˆλ‹€. 쀑볡 등둝 μ‹œλ„
UQ-002 400 μœ νš¨ν•˜μ§€ μ•Šμ€ μ‚¬μš©μž IDμž…λ‹ˆλ‹€. userIdλŠ” μ–‘μˆ˜μ—¬μ•Ό ν•©λ‹ˆλ‹€. userIdκ°€ nullμ΄κ±°λ‚˜ 0 μ΄ν•˜
UQ-003 400 μœ νš¨ν•˜μ§€ μ•Šμ€ 큐 μ΄λ¦„μž…λ‹ˆλ‹€. 큐 이름은 λΉ„μ–΄μžˆμ„ 수 μ—†μŠ΅λ‹ˆλ‹€. queueκ°€ nullμ΄κ±°λ‚˜ 빈 λ¬Έμžμ—΄
UQ-004 400 μœ νš¨ν•˜μ§€ μ•Šμ€ count κ°’μž…λ‹ˆλ‹€. countλŠ” 0 이상이어야 ν•©λ‹ˆλ‹€. countκ°€ nullμ΄κ±°λ‚˜ 음수
UQ-005 400 λŒ€κΈ°μ—΄μ΄ 가득 μ°ΌμŠ΅λ‹ˆλ‹€. μ΅œλŒ€ μš©λŸ‰: Nλͺ… λŒ€κΈ°μ—΄ μš©λŸ‰ 초과

μ—λŸ¬ 응닡 ν˜•μ‹

Example

{
  "code": "UQ-001",
  "reason": "이미 λ“±λ‘λœ μ‚¬μš©μžμž…λ‹ˆλ‹€."
}

πŸ” 인증 및 κΆŒν•œ

ν˜„μž¬ 버전

  • 인증 μ—†μŒ (개발/ν…ŒμŠ€νŠΈ 단계)
  • user_idλ₯Ό 쿼리 νŒŒλΌλ―Έν„°λ‘œ 전달

ν–₯ν›„ κ°œμ„  (ν”„λ‘œλ•μ…˜)

1. JWT 기반 인증
   - Authorization: Bearer {token}
   - 토큰에 userId 포함

2. API Key 인증 (κ΄€λ¦¬μž API)
   - X-API-Key: {key}
   - /api/v1/queue/allow λ“± κ΄€λ¦¬μž API 보호

3. Rate Limiting
   - μ‚¬μš©μžλ‹Ή λΆ„λ‹Ή μš”μ²­ 수 μ œν•œ
   - IP 기반 μ œν•œ

πŸš€ μ‚¬μš© μ‹œλ‚˜λ¦¬μ˜€

μ‹œλ‚˜λ¦¬μ˜€ 1: 일반 μ‚¬μš©μž λŒ€κΈ° 및 μ§„μž…

# 1. λŒ€κΈ°μ—΄ 등둝
curl -X POST "http://localhost:9010/api/v1/queue?user_id=100"
# β†’ {"rank": 10}

# 2. μˆœμœ„ 주기적 쑰회 (폴링)
curl "http://localhost:9010/api/v1/queue/rank?user_id=100"
# β†’ {"rank": 7}

# 3. μ§„μž… ν—ˆμš© μ—¬λΆ€ 확인
curl "http://localhost:9010/api/v1/queue/allowed?user_id=100"
# β†’ {"allowed": false}

# ... λŒ€κΈ° ...

# 4. μ§„μž… ν—ˆμš© 확인
curl "http://localhost:9010/api/v1/queue/allowed?user_id=100"
# β†’ {"allowed": true}

# 5. 토큰 생성
curl "http://localhost:9010/api/v1/queue/touch?user_id=100"
# β†’ 토큰 λ°˜ν™˜ + μΏ ν‚€ μ„€μ •

# 6. μ„œλΉ„μŠ€ 이용
# (메인 μ„œλΉ„μŠ€λ‘œ λ¦¬λ‹€μ΄λ ‰νŠΈ, 토큰 검증)

μ‹œλ‚˜λ¦¬μ˜€ 2: VIP μ‚¬μš©μž

# 1. VIP둜 등둝
curl -X POST "http://localhost:9010/api/v1/queue?user_id=200&is_vip=true"
# β†’ {"rank": 1}  (일반 μ‚¬μš©μžλ³΄λ‹€ μš°μ„ μˆœμœ„)

# 2. λΉ λ₯Έ μ§„μž…
# VIPλŠ” 일반 μ‚¬μš©μžλ³΄λ‹€ λ¨Όμ € μ§„μž… ν—ˆμš©λ¨

μ‹œλ‚˜λ¦¬μ˜€ 3: κ΄€λ¦¬μž 운영

# 1. ν˜„μž¬ 톡계 확인
curl "http://localhost:9010/api/v1/queue/statistics"
# β†’ {"queue": "default", "waitingCount": 150, "allowedCount": 50}

# 2. 20λͺ… μ§„μž… ν—ˆμš©
curl -X POST "http://localhost:9010/api/v1/queue/allow?count=20"
# β†’ {"requestCount": 20, "allowedCount": 20}

# 3. 전체 이λ ₯ 확인
curl "http://localhost:9010/api/v1/queue/history/all?count=50"
# β†’ [...]

πŸ“ μΆ”κ°€ 정보

Rate Limiting (ꢌμž₯사항)

ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œλŠ” λ‹€μŒκ³Ό 같은 μ œν•œμ„ ꢌμž₯ν•©λ‹ˆλ‹€:

API μ œν•œ
POST /api/v1/queue μ‚¬μš©μžλ‹Ή 1뢄에 1회
GET /api/v1/queue/rank μ‚¬μš©μžλ‹Ή 1뢄에 10회
GET /api/v1/queue/allowed μ‚¬μš©μžλ‹Ή 1뢄에 10회
POST /api/v1/queue/allow κ΄€λ¦¬μžλ§Œ, 1뢄에 10회

CORS μ„€μ •

# application.yml
spring:
  webflux:
    cors:
      allowed-origins: "*"
      allowed-methods: GET,POST
      allowed-headers: "*"

API 버저닝

ν˜„μž¬ 버전: v1

ν–₯ν›„ 버전 관리:

/api/v1/queue    # ν˜„μž¬ 버전
/api/v2/queue    # 미래 버전 (ν•˜μœ„ ν˜Έν™˜ 깨질 λ•Œ)

πŸ§ͺ API ν…ŒμŠ€νŠΈ

Postman Collection

ν”„λ‘œμ νŠΈμ— ν¬ν•¨λœ Postman Collection을 μ‚¬μš©ν•˜μ—¬ μ‰½κ²Œ ν…ŒμŠ€νŠΈν•  수 μžˆμŠ΅λ‹ˆλ‹€.

docs/postman/Flow-API.postman_collection.json

curl 슀크립트

# test-api.sh
#!/bin/bash

BASE_URL="http://localhost:9010"

echo "1. λŒ€κΈ°μ—΄ 등둝"
curl -X POST "$BASE_URL/api/v1/queue?user_id=100"

echo "\n2. μˆœμœ„ 쑰회"
curl "$BASE_URL/api/v1/queue/rank?user_id=100"

echo "\n3. 톡계 쑰회"
curl "$BASE_URL/api/v1/queue/statistics"

πŸ“ README둜 λŒμ•„κ°€κΈ° | πŸ“‹ 포트폴리였 | πŸ›οΈ μ•„ν‚€ν…μ²˜

API κ΄€λ ¨ λ¬Έμ˜μ‚¬ν•­μ€ 이슈둜 λ“±λ‘ν•΄μ£Όμ„Έμš”.