API 설계 (API Design)

목차


API 설계란

API 설계(API Design) 는 서비스 내부 기능을 외부나 다른 서비스가 안정적으로 사용할 수 있도록 인터페이스를 정의하는 작업입니다.

이 문서는 계약 모델과 인터페이스 경계에 집중합니다. 레이트 리밋의 기준 단위와 알고리즘은 레이트 리미팅 (Rate Limiting), timeout/retry/circuit breaker 정책은 복원력 패턴 (Timeout, Retry, Circuit Breaker), 포맷 호환성은 직렬화 (Serialization) 문서를 함께 보면 더 직접적입니다.

좋은 API는 단순히 동작만 하는 것이 아니라 다음을 만족해야 합니다.

  • 이해하기 쉬움: 이름과 구조만 봐도 의도가 드러남
  • 일관성: 비슷한 패턴이 반복되어 학습 비용이 낮음
  • 확장성: 필드와 기능을 추가해도 호환성을 크게 깨지 않음
  • 운영 가능성: 인증, 로깅, 레이트 리밋, 에러 추적이 가능함

API는 클라이언트와 서버 사이의 계약이기 때문에, 한 번 공개되면 내부 코드보다 바꾸기 어렵습니다.


좋은 API가 가져야 할 기준

면접에서는 “좋은 API란 무엇인가”를 물을 때가 많습니다.
보통 다음 기준으로 설명하면 안정적입니다.

  • 명확한 리소스 또는 작업 모델
  • 예측 가능한 요청/응답 형식
  • 적절한 상태 코드와 오류 메시지
  • 버전 관리 전략
  • 인증과 권한 처리 위치
  • 멱등성, 복원력 정책, 레이트 리밋 고려

즉, API 설계는 URL 몇 개 정하는 문제가 아니라
클라이언트가 오래 안전하게 호출할 수 있는 계약을 만드는 작업입니다.


리소스 중심과 작업 중심 설계

API를 설계할 때 먼저 생각할 점은 이것이 리소스 중심인지 작업 중심인지입니다.

  • 리소스 중심: 주문, 사용자, 상품 같은 엔티티를 다룸
  • 작업 중심: 재시도, 승인, 배치 실행, 보고서 생성 같은 행동을 다룸

REST 스타일에서는 보통 리소스를 URI로 표현하고 HTTP 메서드 의미를 같이 사용합니다.1

예를 들어:

  • GET /orders/123
  • POST /orders
  • PUT /orders/123
  • DELETE /orders/123

하지만 모든 문제가 리소스 모델로 깔끔하게 떨어지지는 않습니다.

  • 결제 승인
  • 파일 변환 시작
  • 대량 재처리
  • 비동기 잡 트리거

이런 작업은 /orders/{id}/cancel, /jobs/reindex 같은 작업 중심 API가 더 자연스러울 수 있습니다.

중요한 점은 REST 순수성보다 사용자와 클라이언트가 이해하기 쉬운 모델입니다.


REST, GraphQL, gRPC 비교

API 방식은 하나가 절대적으로 우월한 것이 아니라 사용 맥락에 따라 달라집니다.

항목 REST GraphQL gRPC
핵심 모델 리소스와 HTTP 메서드 단일 엔드포인트와 스키마 기반 질의 RPC 호출과 서비스 정의
장점 단순하고 널리 통용됨 필요한 필드만 조회 가능 성능과 계약 기반 통신에 강함
단점 over-fetching / under-fetching 가능 캐시, 복잡도 제어가 어려울 수 있음 브라우저 친화성, 디버깅 편의성은 낮을 수 있음
적합한 경우 공개 API, 범용 웹 API 복잡한 UI 조합 조회 내부 서비스 간 고성능 통신

REST

  • 장점: HTTP 의미와 잘 맞고, 캐시와 상태 코드 모델을 활용하기 쉽습니다.
  • 주의점: 화면별로 필요한 데이터가 다르면 여러 번 호출하거나 과다 조회가 발생할 수 있습니다.

GraphQL

GraphQL은 보통 단일 엔드포인트에서 스키마를 기준으로 원하는 필드를 질의합니다.23

  • 장점: 클라이언트가 필요한 필드만 요청 가능
  • 주의점: 너무 자유로운 질의는 N+1, 복잡도 폭증, 캐시 난이도 문제를 만들 수 있음

GraphQL은 query와 mutation을 구분하며, query에 대해서는 GET을 허용할 수 있지만 mutation은 POST를 사용해야 합니다.2

gRPC

gRPC는 .proto 파일로 서비스와 메시지를 정의하고, 이를 바탕으로 클라이언트/서버 코드를 생성하는 RPC 방식입니다.4

  • 장점: 강한 계약, 효율적인 직렬화, 서비스 간 통신에 유리
  • 주의점: 브라우저 직접 호출이나 사람이 curl로 테스트하는 경험은 REST보다 불편할 수 있음

또한 gRPC는 표준 health checking 서비스와 client-side health checking을 지원합니다.5

관련 세부 주제는 gRPC 문서와 함께 설명하면 좋습니다. JSON, Protocol Buffers, schema evolution 같은 포맷 관점은 직렬화 (Serialization) 문서가 더 직접적입니다.


버전 관리 전략

API는 한 번 공개되면 쉽게 없앨 수 없기 때문에 버전 관리 전략이 중요합니다.

대표 방식은 다음과 같습니다.

  • URL 버전: /v1/orders
  • 헤더 버전: Accept: application/vnd.company.v1+json
  • 필드 확장 중심: 하위 호환을 유지하며 새 필드 추가
방식 장점 주의점
URL 버전 이해하기 쉽고 운영이 단순함 버전이 늘수록 경로가 늘어남
헤더 버전 URI를 깔끔하게 유지 가능 디버깅과 문서화가 더 어려울 수 있음
필드 확장 중심 클라이언트 충격을 줄이기 쉬움 하위 호환 원칙을 엄격히 지켜야 함

실무에서는 “모든 변경마다 새 버전”보다
breaking change에만 버전을 올리고, 나머지는 호환 가능한 확장으로 처리하는 경우가 많습니다.


멱등성과 오류 처리

분산 시스템에서 API는 네트워크 오류로 재시도될 수 있습니다.
그래서 멱등성(Idempotency) 과 오류 처리 전략이 중요합니다.

RFC 9110은 PUT, DELETE, 그리고 safe method를 멱등한 메서드로 정의합니다.1

하지만 실무에서는 HTTP 메서드 의미만으로 충분하지 않을 때가 많습니다.

  • 결제 승인 API
  • 주문 생성 API
  • 환불 요청 API

이런 요청은 POST 이더라도 Idempotency-Key 같은 별도 키를 두어 중복 처리를 막는 경우가 많습니다.

HTTP 메서드 의미와 비즈니스 멱등성을 어떻게 나눌지, Idempotency-Key 저장 전략을 더 깊게 보려면 멱등성과 재시도 (Idempotency and Retry) 문서를 같이 보면 좋습니다. timeout budget, retryable error, circuit breaker 같은 복원력 일반론은 복원력 패턴 (Timeout, Retry, Circuit Breaker) 문서와 연결하면 좋습니다.

오류 처리 시에는 다음을 같이 설계해야 합니다.

  • 상태 코드: 2xx, 4xx, 5xx 의미 구분
  • 오류 코드: 기계가 처리할 수 있는 내부 코드
  • 메시지: 사람이 이해할 수 있는 설명
  • 추적 정보: request id, trace id

좋은 API 오류 응답은 “에러가 났다”가 아니라
왜 실패했고, 클라이언트가 재시도해야 하는지 수정해야 하는지를 구분해 줍니다.


페이지네이션과 조회 설계

조회 API는 성능과 사용성을 같이 봐야 합니다.

대표 패턴은 다음과 같습니다.

  • Offset 기반 페이지네이션: 구현이 단순하지만 큰 offset에서 비효율적일 수 있음
  • Cursor 기반 페이지네이션: 대용량 목록과 실시간 데이터에 더 안정적
  • 필터와 정렬: 허용 가능한 필드와 인덱스 전략을 같이 고려해야 함

API 설계 시 자주 보는 실수는 다음입니다.

  • 무제한 목록 조회 허용
  • 정렬 기준이 불명확함
  • 필터 조합이 너무 자유로워 DB 인덱스를 못 탐
  • 응답 필드가 과도하게 큼

즉, 조회 API는 프론트엔드 편의성만이 아니라
DB 실행 계획과 캐시 전략까지 같이 고려한 설계여야 합니다.


API Gateway와 정책 집행

API가 많아지면 공통 정책을 어느 계층에서 처리할지 정해야 합니다.

API Gateway에서 자주 담당하는 역할은 다음과 같습니다.

  • 인증 위임
  • 레이트 리밋
  • 라우팅
  • TLS 종료
  • 공통 로깅과 메트릭
  • 버전별 진입점 관리

다만 모든 비즈니스 규칙을 Gateway에 몰아넣는 것은 주의해야 합니다.

  • Gateway가 비대해질 수 있음
  • 서비스별 예외 로직이 과도하게 섞일 수 있음
  • 디버깅 경로가 복잡해질 수 있음

그래서 일반적으로는 공통 정책은 Gateway,
도메인 규칙과 세부 권한은 각 서비스에서 처리하는 편이 균형이 좋습니다.

레이트 리밋의 기준 단위, burst 허용, 429Retry-After 같은 상세 정책은 레이트 리미팅 (Rate Limiting) 문서가 더 직접적인 심화 자료입니다.


API 설계의 트레이드오프

  • REST: 단순성과 범용성이 좋지만, 복잡한 화면 조합에는 비효율적일 수 있습니다.
  • GraphQL: 클라이언트 유연성이 좋지만, 운영 통제가 어려워질 수 있습니다.
  • gRPC: 내부 서비스 계약과 성능에 강하지만, 외부 공개 API에는 진입 장벽이 있을 수 있습니다.

또한 API 설계는 “예쁘게 설계하는 일”보다 다음의 균형 문제입니다.

  • 단순성 vs 유연성
  • 즉시 개발 속도 vs 장기 호환성
  • 공개 API 안정성 vs 내부 API 최적화

좋은 답변은 특정 스타일을 신앙처럼 밀지 않고,
누가 쓰는 API인지와 어떤 운영 요구가 있는지에 맞춰 설명합니다.


면접 포인트

  • 좋은 API는 호출 가능하기만 한 인터페이스가 아니라, 오래 유지 가능한 계약입니다.
  • REST, GraphQL, gRPC는 대체 관계라기보다 문제와 소비자에 따라 선택하는 도구입니다.
  • 멱등성은 재시도 가능한 분산 환경에서 매우 중요한 설계 포인트입니다.
  • 버전 관리는 breaking change를 어떻게 다룰지에 대한 전략으로 설명하는 편이 좋습니다.
  • Gateway는 공통 정책 처리에 좋지만, 도메인 로직까지 과하게 넣으면 복잡도가 커집니다.

참고 자료