API 설계 베스트 프랙티스 - 확장성 있는 웹서비스를 위한 필수 원칙

5 조회

확장성 있는 API 설계의 핵심은 리소스 중심 설계, 명확한 버저닝, 레이트 리밋, 캐싱 전략이다.

이 글은 웹서비스 API를 처음 설계하거나 기존 API의 문제를 개선하려는 백엔드 개발자와 풀스택 개발자를 대상으로 작성되었다. 2025~2026년 기준 업계 표준 RESTful API 설계 원칙과 실전 적용 방법을 정리한다.

API 설계 원칙 개요

REST API란 무엇이고 왜 중요한가?

REST(Representational State Transfer) API란 웹 리소스를 HTTP 프로토콜을 통해 표준화된 방식으로 주고받는 인터페이스다. 클라이언트(프론트엔드, 모바일 앱, 외부 서비스)와 서버가 통신하는 계약(Contract) 역할을 한다.

좋은 API는 단순히 동작하는 것을 넘어, 수천 명의 개발자가 쉽게 사용하고, 트래픽이 늘어나도 안정적으로 작동하며, 기능 추가 시 하위 호환성을 유지해야 한다. 이것이 API 설계를 처음부터 잘 해야 하는 이유다.

리소스 중심 URL 설계 원칙은 무엇인가?

REST의 핵심은 동사가 아닌 명사(리소스)로 URL을 설계하는 것이다. 동작은 HTTP 메서드(GET, POST, PUT, DELETE)로 표현한다.

나쁜 예 (동사 중심)좋은 예 (리소스 중심)
GET /getUsersGET /users
POST /createUserPOST /users
POST /deleteUser/123DELETE /users/123
GET /getUserPosts/123GET /users/123/posts
POST /updatePostPUT /posts/123

컬렉션(목록)은 복수형으로, 단일 리소스는 ID를 포함해 표현한다. 예를 들어 사용자 목록은 /users, 특정 사용자는 /users/123, 그 사용자의 게시글은 /users/123/posts로 설계한다(출처: Microsoft Azure Architecture Center, API Design Best Practices).

API 버저닝은 왜 필요하고 어떻게 해야 하나?

API는 시간이 지나면서 변경이 불가피하다. 기존 클라이언트가 사용 중인 API를 갑자기 바꾸면 장애가 발생한다. 따라서 버저닝(Versioning)이 필수다.

URL 버저닝(/v1/users)이 가장 명확한 방식이다. 버전이 모든 요청 경로에 포함되어 라우팅이 쉽고, 어떤 버전을 사용하는지 한눈에 알 수 있다.

  • 파괴적 변경(Breaking Change): 필드 삭제, 응답 구조 변경 → 새 버전(/v2/) 필요
  • 비파괴적 변경(Non-breaking Change): 선택적 필드 추가 → 기존 버전 유지 가능

캐싱으로 API 성능을 어떻게 높이나?

HTTP 캐싱은 서버 부하를 줄이고 클라이언트 응답 속도를 높이는 핵심 전략이다. REST API에서 캐싱은 Cache-Control, ETag, Last-Modified 헤더로 구현한다(출처: Strapi RESTful API Design Guide, 2025).

  • Cache-Control: max-age=3600: 응답을 1시간 캐시
  • ETag: 리소스의 고유 버전 식별자. 변경이 없으면 304 Not Modified 반환
  • Last-Modified: 마지막 수정 시각. 조건부 요청에 활용

캐싱 가능한 리소스(사용자 프로필, 상품 목록 등)와 캐싱 불가 리소스(결제, 인증 등)를 명확히 구분해 적용해야 한다.

레이트 리밋(Rate Limiting)은 왜 반드시 필요한가?

레이트 리밋이란 단위 시간당 허용하는 API 요청 수를 제한하는 기능이다. DoS(서비스 거부) 공격 방지, 공평한 리소스 분배, 과도한 사용 방지에 필수적이며, 확장 가능한 플랫폼에서는 선택이 아닌 필수다(출처: Aezion API Design Best Practices, 2025).

응답 헤더에 레이트 리밋 정보를 포함해 클라이언트가 사용량을 알 수 있게 해야 한다.

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 750
X-RateLimit-Reset: 1740441600

한도 초과 시 429 Too Many Requests 상태 코드와 함께 언제 요청이 가능한지(Retry-After) 안내해야 한다.

좋은 API 응답 구조는 어떻게 설계하나?

API 설계 실전 팁

일관된 응답 구조는 API를 사용하는 개발자의 경험을 크게 향상시킨다.

성공 응답 예시:

{
  "success": true,
  "data": { "id": "123", "name": "홍길동" },
  "meta": { "total": 100, "page": 1, "limit": 20 }
}

오류 응답 예시:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "이메일 형식이 올바르지 않습니다.",
    "field": "email"
  }
}

HTTP 상태 코드도 정확하게 사용해야 한다. 200(성공), 201(생성 성공), 400(잘못된 요청), 401(인증 필요), 403(권한 없음), 404(리소스 없음), 429(레이트 리밋 초과), 500(서버 오류)가 기본이다.

API 문서화와 모니터링은 어떻게 해야 하나?

API는 문서가 없으면 존재하지 않는 것과 같다. OpenAPI Specification(구 Swagger)은 기계가 읽을 수 있는 API 문서 표준으로, 자동으로 인터랙티브한 문서 페이지를 생성한다(출처: Group107 API Development Best Practices, 2025).

모니터링 측면에서는 응답 지연(Latency), 오류율(Error Rate), 초당 요청 수(RPS)를 핵심 지표로 추적해야 한다. Prometheus, Grafana, Datadog 같은 도구가 일반적으로 사용된다.

자주 묻는 질문 (FAQ)

REST API와 GraphQL 중 어느 것을 선택해야 하나?

REST API는 단순하고 표준화되어 있어 대부분의 경우에 적합하다. GraphQL은 클라이언트가 필요한 데이터만 정확히 요청할 수 있어 복잡한 데이터 요구사항이나 모바일 앱에서 유리하다. 일반적으로 REST로 시작해 필요 시 GraphQL을 도입하는 방식이 권장된다.

API 인증은 어떤 방식을 써야 하나?

공개 API에는 API 키, 내부 서비스 간에는 JWT(JSON Web Token) 또는 OAuth 2.0이 일반적으로 사용된다. 모든 API 통신은 반드시 HTTPS로 암호화해야 한다.

API 버전을 언제 올려야 하나?

기존 클라이언트의 코드를 수정하지 않으면 동작하지 않는 '파괴적 변경'이 발생할 때 버전을 올린다. 필드 추가, 선택적 파라미터 추가는 파괴적 변경이 아니므로 버전을 올릴 필요가 없다.

페이지네이션은 어떻게 구현해야 하나?

오프셋 기반(?page=2&limit=20)과 커서 기반(?cursor=abc123) 두 방식이 있다. 데이터가 자주 변경되거나 대용량이라면 커서 기반이 더 안정적이다.

API 설계 시 보안을 위해 꼭 지켜야 할 원칙은?

입력값 검증(모든 사용자 입력은 신뢰하지 말 것), HTTPS 강제 적용, 민감 데이터 응답 제외, 레이트 리밋 적용, 인증·권한 분리가 기본 원칙이다.

공유