zerovoids.dev

왜, 그리고 제대로

published 2026-07-17part 01 / 04
zerovoids-httperror-normalizationvendor-errorsapi-integration

이전 직장에서 계속 되풀이되던 이슈가 있었다. 백엔드 응답 규격이 프로젝트마다 다르거나, 공용 API와 섞이거나, 여러 엔드포인트를 함께 물어 프론트를 짜야 하는 상황이 잦았다.

성공 응답은 그럭저럭 정규화해 썼다. 백엔드 원 응답과 타입을 별도 패키지에 두고, 프론트 프로젝트에서 엔드포인트마다 매퍼로 '쓸 수 있는 형식'으로 매핑했다. 하지만 실패는 그냥 흘려보냈다. 사실 흘려보냈다기보다는 — 대응은 했지만, 이상적인 방법을 찾을 여유가 없었던 쪽에 가깝다.

그래서 프론트엔드 인터셉터엔 이런 분기가 쌓이거나,

interceptor.ts
if (err.response?.data?.errors?.[0]?.code === 'missing_field') { … }

API 종류마다 인터셉터를 따로 두고, 각자의 에러 처리 로직을 그 안에 심었다.

잘 만들고 싶었다

기왕 하는 거면 제대로 만들고 싶었다. 아직 추상적인 내 불편함의 원인과 해결 방법을 한 번 넓혀서 생각해보고 싶었다 — 이런 이슈를 이미 푸는 방법이 있었는지, 내 문제를 더 확장했을 때 이 패키지가 어디까지 감당할 수 있을지.

시장에 주인이 없는 니치는 딱 하나였다: 벤더마다 다른 에러 모양을, 클라이언트에 종속되지 않고, 하나의 타입으로 정규화하는 레이어. 나머지는 처음부터 긋지 않았다.

해결 방식은 표준적으로 가고 싶었다. 근거 있는 방식으로 — 키 이름도, 인터페이스도, 타입까지도. 그냥 작동하는 자체 규격이 아니라, 공개했을 때 설득이 되는 근거로.

그렇게 짓고 싶은 건 해결책만이 아니었다. 프로젝트 자체도 — 잘 갖춘 툴링과 믿을 수 있는 CI/CD, AI가 초안을 잡는 커밋 규약까지 — 라이브러리다운 바닥 위에 세우고 싶었다. 공개 라이브러리의 신뢰는 코드가 아니라, 코드를 감싼 그 전부에서 나온다고 믿었으니까.

그러니 바닥부터 이야기하는 게 맞겠다.