신입 때 API는 “요청 보내면 JSON 오는 것”처럼 보이지만, 운영이 시작되면 API는 곧 서비스의 얼굴이자 팀 간 계약서가 됩니다. 프론트/모바일/파트너/내부 서비스가 모두 API에 의존하므로, API가 흔들리면 전체 시스템이 같이 흔들립니다.
그래서 API 설계는 단순히 엔드포인트를 만드는 일이 아니라, 변경 비용을 통제하고 장애를 줄이는 설계에 가깝습니다.
“계약”이라는 표현이 중요한 이유는, API가 단지 데이터 전달 통로가 아니라 입력 검증, 권한, 에러 규약, 버전 호환, 성능 특성까지 포함하기 때문입니다. 즉, API는 ‘기능’이 아니라 운영 가능한 시스템의 규격입니다.
“API는 기능을 노출하는 창구이자,
변경과 장애를 통제하는 경계다.”
💡 TIP / “API 문서”는 옵션이 아니라 필수
API는 결국 계약이기 때문에, 코드만 보고 맞추면 운영에서 깨집니다. 실무에서는 요청/응답 스키마, 상태코드, 에러 규약, 인증 방식, 제한(쿼터)까지 문서화(OpenAPI/Swagger 등)해두는 게 기본입니다.
// [요청] GET /v1/users/{userId}
GET /v1/users/42
Authorization: Bearer <access_token>
// [성공 응답] 200 OK
{
"userId": 42,
"name": "Jho",
"email": "jho@example.com",
"status": "ACTIVE",
"createdAt": "2026-02-20T10:00:00Z"
}
// [실패 응답] 404 Not Found (에러 규약)
{
"error": {
"code": "USER_NOT_FOUND",
"message": "사용자를 찾을 수 없습니다.",
"traceId": "b8b1f6a2-...."
}
}
여기서 중요한 건 “응답이 JSON이다”가 아니라, 클라이언트가 예측 가능한 규칙이 있다는 점입니다. 실패 시에는 상태 코드로 분류하고, body에는 code/message/traceId 같은 공통 규약을 유지하면 운영에서 디버깅이 빨라집니다.
👍 GOOD
- 상태코드가 의미대로 동작(4xx/5xx 구분)
- 에러 응답이 항상 동일한 구조
- traceId로 로그/트레이싱과 연결 가능
- 스키마가 문서(OpenAPI)로 고정됨
👎 BAD
- 실패해도 무조건 200 + error 문자열
- 에러 구조가 API마다 제각각
- DB 컬럼명이 그대로 노출(내부 모델 누수)
- 문서 없이 “감으로” 맞추는 통신
💡 TIP / “API는 항상 실패한다”를 기본값으로 두기
네트워크는 지연되고, 클라이언트는 재시도하며, 서버는 일시적으로 과부하가 옵니다. 그래서 API 설계에는 타임아웃, 재시도 전략, 멱등성 키, 표준 에러, 서킷브레이커 같은 “실패 대비”가 같이 들어가야 운영이 편해집니다.
✅ 핵심 요약
- ✔️ API는 요청/응답만이 아니라 에러·권한·버전·운영 규칙까지 포함한 “계약”이다.
- ✔️ 좋은 API는 예측 가능하고, 상태코드/에러 규약이 일관되며, 변경에 강하다.
- ✔️ 실무에서 API는 항상 실패를 전제로 하므로 타임아웃·재시도·멱등성·관측을 설계에 포함해야 한다.
- ✔️ “문서 + 테스트(OpenAPI/계약 테스트)”는 선택이 아니라, 운영에서 깨짐을 막는 안전장치다.