본문으로 건너뛰기
김신건의 로그

[API Design] REST API: 원칙, 자원 모델링, HATEOAS, 버전 관리

· 수정 · 📖 약 2분 · 772자/단어 #rest #api-design #backend #http
REST API Design, REST, RESTful API, Resource modeling, HATEOAS, Richardson Maturity Model, API versioning

정의

REST (Representational State Transfer) 는 Roy Fielding 의 2000년 박사논문에서 정립된 분산 시스템 아키텍처 스타일. HTTP 의 자원 / 표현 / 상태 전이 를 자연스럽게 활용.

IMPORTANT

“REST” 라는 단어는 대부분 실무에서 HTTP+JSON CRUD 를 의미. Fielding 의 순수 REST (HATEOAS 포함) 는 드물게 적용. 이 페이지는 실무 REST진짜 REST 둘 다 정리.

Richardson Maturity Model (REST 의 4 단계)

flowchart TB
    L0[Level 0: 단일 endpoint<br/>POST /api 로 모든 작업] --> L1[Level 1: 자원 분리<br/>GET /users, /orders]
    L1 --> L2[Level 2: HTTP method + status<br/>GET/POST/PUT/DELETE]
    L2 --> L3[Level 3: HATEOAS<br/>응답에 next action 링크]

실무 대부분은 Level 2 에 머문다. Level 3 은 Stripe, GitHub API 의 일부 정도.

자원 모델링

좋은 패턴나쁜 패턴
GET /users/42GET /getUser?id=42
POST /users (생성)POST /createUser
DELETE /users/42POST /deleteUser
GET /users/42/ordersGET /userOrders?uid=42
POST /users/42/email/verify (action)GET /verifyUserEmail?uid=42

규칙:

  1. 명사로 자원 표현 (users, orders)
  2. 복수형 권장 (users not user)
  3. 상태 변경 은 HTTP method 로
  4. 체이닝 자원으로 관계 표현 (/users/42/orders/9)
  5. 비-CRUD action복합 명사 (/orders/9/cancel, /payments/p_123/refund)

HTTP Method 매핑

Method멱등안전사용
GETOO조회
HEADOO헤더만
POSTXX생성, 비-멱등 action
PUTOX전체 교체
PATCHX (대개)X부분 갱신
DELETEOX삭제

NOTE

PUTidempotent. 두 번 호출 = 한 번 호출 결과 같음. POST매번 새 자원 생성.

Status Code 패턴

코드사용
200성공 (GET, PUT, PATCH)
201생성 (POST). Location 헤더로 새 자원 URL
202비동기 접수
204본문 없음 성공 (DELETE)
400입력 형식 / 필수 누락
401인증 필요
403인증 됐지만 권한 없음
404자원 없음
409충돌 (중복, 동시성)
422형식은 OK, 의미 검증 실패
429rate limit 초과

API 버전 관리

flowchart LR
    Q{버전 표시 방법}
    Q --> URL["URL: /v1/users<br/>/v2/users"]
    Q --> Header["헤더: Accept: application/vnd.api+json;v=2"]
    Q --> Query["Query: /users?api-version=2"]
방식장점단점
URL (/v1/)명시적, 캐싱 친화URL 영구 변경
Accept 헤더URL 깔끔디버깅 / 캐시 어려움
Query단순URL 변형

Stripe날짜 기반 버전 (Stripe-Version: 2023-10-16). 가장 세밀하고 안전한 호환성.

페이지네이션

flowchart LR
    A[Offset/Limit<br/>?offset=20&limit=10] --> B[페이지 N 빠른 점프 가능]
    C[Cursor<br/>?cursor=abc123] --> D[연속 스트림, 정확]
    E[Page/Size<br/>?page=3&size=10] --> F[옛 패턴]
방식장점단점
Offset임의 점프큰 offset 시 O(N) DB query
Cursor빠름, 정확임의 점프 불가
Keysetoffset + cursor 의 장점구현 복잡

TIP

대량 데이터 + 무한 스크롤 = 거의 항상 cursor 기반. Stripe, GitHub, Twitter API 모두.

응답 포맷 (envelope)

{
  "data": [...],
  "meta": {
    "total": 1024,
    "page": 1,
    "per_page": 20
  },
  "links": {
    "self": "...",
    "next": "...",
    "prev": null
  }
}

또는 납작 (JSON:API 스펙):

{
  "data": [{ "id": "1", "type": "users", "attributes": { ... } }]
}

CAUTION

envelope 의 너무 깊은 nesting클라이언트 코드 복잡. flat + 표준 (RFC 7807 problem details for errors) 권장.

에러 응답 (RFC 7807)

{
  "type": "https://example.com/probs/validation",
  "title": "Validation failed",
  "status": 422,
  "detail": "Email is required",
  "instance": "/requests/12345",
  "errors": [
    { "field": "email", "code": "REQUIRED" }
  ]
}

HATEOAS

응답에 다음 가능 action 의 링크 포함:

{
  "id": "o_123",
  "status": "pending",
  "links": {
    "self": "/orders/o_123",
    "cancel": "/orders/o_123/cancel",
    "pay": "/orders/o_123/pay"
  }
}

NOTE

클라이언트가 URL 을 미리 알 필요 없이 응답의 링크만 따라 가는 진짜 REST. 실무에서는 드물지만 GitHub API 가 좋은 예.

흔한 함정

WARNING

  1. /users/getById 같은 동사 URL = REST 의 자원 사상 위반.
  2. 모든 변경에 PUT = PATCH 가 적절한 부분 갱신에도 PUT 사용 → race condition.
  3. POST비-멱등 위험 = 네트워크 재시도 시 중복 생성. Idempotency-Key 헤더로 해결.
  4. 버전 없이 시작 = breaking change 시 모든 클라이언트 동시 마이그레이션 강요.

관련 위키

이 글의 용어 (5개)
[API Design] GraphQL: 단일 endpoint, N+1, persisted queriesapi-design
정의 GraphQL (Facebook, 2015) 은 클라이언트가 필요한 필드만 명시 하는 query language + 런타임. 단일 endpoint, typed schema,…
[API Design] OpenAPI / Swagger: 스펙, 코드 생성, contract testingapi-design
정의 OpenAPI Specification (OAS) 은 REST API 를 기술하는 YAML/JSON 형식. 옛 이름 Swagger. 2017 부터 OpenAPI Initia…
[Network] gRPC: HTTP/2 + Protobuf, 4가지 streaming 패턴network
정의 gRPC 는 HTTP/2 위에서 Protobuf 직렬화 로 동작하는 고성능 RPC 프레임워크. Google 내부 Stubby 의 오픈소스 후계. 핵심 4가지: 1. Prot…
[Network] HTTP/1.1: keep-alive, pipelining, chunked transfernetwork
정의 HTTP/1.1 (1997, RFC 9112 으로 재정리) 는 텍스트 기반 stateless request/response 프로토콜. 2026 시점에도 대부분의 트래픽이 H…
[Pattern] Idempotency Keys: 중복 요청 안전 처리distributed-systems
정의 Idempotency = 같은 요청을 N번 보내도 결과가 1번과 동일. 분산 시스템 / 결제 / API 의 안전망. [!IMPORTANT] 네트워크는 항상 timeout /…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기