"어라? 이 API 요청이 왜 403 에러를 반환하지..."
최근 한 프로젝트에서 이런 상황에 직면했습니다. 클라이언트로부터 "API가 제대로 작동하지 않는다"는 연락을 받고 급히 조사했더니, 인증 토큰의 만료라는 단순한 문제였습니다. 하지만 클라이언트에게는 "403이 뭐지?"라는 상태였습니다.
이 경험을 통해 API 에러코드를 이해하기 쉽게 설명하는 것의 중요성을 절실히 느꼈습니다. 특히 Swagger를 사용한 API 개발에서는 에러코드의 적절한 정의와 설명이 개발 효율성과 사용자 경험을 크게 좌우합니다.
이 글에서는 Swagger에서 자주 사용되는 HTTP 상태 코드의 의미와 실제 사용법에 대해 설명합니다. API 개발에 관여하는 엔지니어 분들께 참고가 되길 바랍니다.
Swagger의 에러코드는 기본적으로 HTTP 상태 코드를 따릅니다. 특히 중요한 것은 다음 5가지입니다.
요청이 잘못되어 서버가 처리할 수 없음을 나타냅니다. 예를 들어, 필수 필드의 누락이나 잘못된 형식의 데이터 등이 있을 수 있습니다.
/users:
post:
summary: 사용자 등록 API
responses:
'400':
description: 요청이 잘못되었습니다. 필수 항목의 누락이나 데이터 형식의 오류가 있습니다.
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Email format is invalid"
실제 개발 현장에서는 "어디가 잘못되었는지"를 구체적으로 보여주는 것이 중요합니다. 예를 들어 "이메일 주소의 형식이 잘못되었습니다"와 같은 상세한 에러 메시지를 반환하면 API를 사용하는 개발자가 도움을 받을 수 있습니다.
참조하다:https://developer.mozilla.org/ko/docs/Web/HTTP/Reference/Status/400
요청을 처리하기 위해 인증이 필요함을 나타냅니다. 사용자가 로그인하지 않았거나 인증 정보가 올바르지 않은 경우에 발생합니다.
/secure-data:
get:
summary: 보호된 데이터 가져오기
security:
- bearerAuth: []
responses:
'401':
description: 인증이 필요합니다. 유효한 액세스 토큰을 제공해주세요.
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Authentication required"
401 에러는 인증 문제를 나타냅니다. "토큰이 유효하지 않습니다" "인증 정보가 만료되었습니다" 등 구체적인 이유를 보여주면 친절합니다.
사용자가 요청된 리소스에 접근할 권한이 없음을 나타냅니다. 예를 들어, 특정 API에 대한 접근이 허용되지 않은 경우 등입니다.
/admin/settings:
put:
summary: 관리자 설정 업데이트
responses:
'403':
description: 이 리소스에 접근할 권한이 없습니다. 관리자 권한이 필요합니다.
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Admin privileges required"
401과 403의 차이를 이해하는 것이 중요합니다. 401은 "누군지 모르는(인증되지 않은)" 상태, 403은 "누군지는 알지만 권한이 없는" 상태를 나타냅니다.
요청된 리소스가 존재하지 않음을 나타냅니다. URL의 오류나 삭제된 리소스 등이 있을 수 있습니다.
/products/{id}:
get:
summary: 상품 상세 정보 가져오기
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'404':
description: 지정된 ID의 상품을 찾을 수 없습니다.
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Product with ID 123 not found"
404 에러는 단순히 "찾을 수 없습니다"만이 아니라, 가능하다면 "어떤 리소스를 찾을 수 없는지"를 구체적으로 보여주면 친절합니다.
서버 측에서 처리 중에 에러가 발생했음을 나타냅니다. 이는 코드의 버그나 서버 구성의 문제 등이 원인일 수 있습니다.
/complex-operation:
post:
summary: 복잡한 처리 실행
responses:
'500':
description: 서버 내부에서 에러가 발생했습니다. 시스템 관리자에게 연락해주세요.
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Internal server error occurred"
requestId:
type: string
example: "req-123456"
500 에러는 서버 측의 문제를 나타냅니다. 운영 환경에서는 상세한 에러 정보를 외부에 노출하지 않도록 주의하면서, 문제 해결을 위한 요청 ID 등을 포함하면 좋습니다.
API 전체에서 일관된 에러 응답 형식을 사용하면 클라이언트 측 구현이 간단해집니다. 예를 들어:
components:
schemas:
Error:
type: object
properties:
code:
type: string
description: 에러 코드
message:
type: string
description: 사람이 읽을 수 있는 에러 메시지
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
이러한 공통 에러 형식을 정의해두면 프론트엔드 개발자가 에러 핸들링을 구현하기 쉬워집니다.
HTTP 상태 코드만으로는 표현할 수 없는 세부적인 에러 상태를 커스텀 에러 코드로 보완하는 방법도 효과적입니다.
/payment:
post:
summary: 결제 처리
responses:
'400':
description: 결제 처리에 실패했습니다
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Error'
- type: object
properties:
code:
example: "PAYMENT_INSUFFICIENT_FUNDS"
message:
example: "잔액 부족으로 결제할 수 없습니다"
"PAYMENT_INSUFFICIENT_FUNDS"와 같은 커스텀 코드를 사용하면 HTTP 상태 코드만으로는 전달할 수 없는 상세한 정보를 제공할 수 있습니다.
Swagger의 강점을 활용하여 에러 코드와 그 대처법을 상세히 문서화합시다.
components:
schemas:
Error:
type: object
properties:
code:
type: string
description: |
에러 코드. 다음 값이 설정됩니다:
- AUTHENTICATION_FAILED: 인증에 실패했습니다
- AUTHORIZATION_FAILED: 권한이 없습니다
- RESOURCE_NOT_FOUND: 리소스를 찾을 수 없습니다
- VALIDATION_ERROR: 입력값이 잘못되었습니다
실제 백엔드가 완성되기 전에도 목 서버와 같은 도구를 활용하여 다양한 에러 상태를 시뮬레이션할 수 있습니다. 이를 통해 프론트엔드 개발자는 초기 단계부터 에러 핸들링 구현을 진행할 수 있습니다.
# 목 서버 설정 예시
paths:
/users/{id}:
get:
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'404':
description: 사용자를 찾을 수 없습니다
content:
application/json:
example:
error: "User with ID 42 not found"
최근 프로젝트에서는 Swagger/OpenAPI 사양과 호환되는 도구를 사용하여 에러 응답의 예를 직관적인 인터페이스로 작성하고 관리하고 있습니다. 특히 Apidog와 같은 도구에서는 드래그 앤 드롭으로 다양한 에러 패턴의 응답 예를 쉽게 만들 수 있어 팀 전체에서 에러 코드의 명명 규칙이나 형식을 통일하기 쉬워집니다.
Swagger에서의 에러 코드 설계는 단순한 기술적 작업이 아니라 API의 사용성과 신뢰성에 직결되는 중요한 요소입니다. 이 글에서 소개한 내용을 요약하면:
이러한 포인트를 잘 지키면 개발자에게도, API를 이용하는 사용자에게도 이해하기 쉽고 사용하기 쉬운 API를 설계할 수 있습니다.
Swagger/OpenAPI 사양을 기반으로 한 도구(특히 Apidog 등)를 활용하면 팀 전체에서 에러 코드 표준화가 크게 진전됩니다. 목 서버 기능을 사용한 에러 상태 테스트도 프론트엔드 개발의 효율화에 크게 기여합니다.