앞 페이지에서 백엔드 골격과 프론트 골격을 각각 세웠다면, 이제 두 축이 실제로 같은 말을 하도록 맞춰야 합니다. 이 단계가 빠지면 프로젝트는 겉으로는 풀스택처럼 보여도, 실제로는 프론트와 백엔드가 서로 다른 가정을 가진 채 따로 움직이게 됩니다.
풀스택 프로젝트에서 가장 흔한 초기 실패는 기능 부족이 아니라 계약 불일치입니다. 백엔드는 snake_case로 응답하고 프론트는 camelCase를 기대하거나, 어떤 API는 { data: ... }를 주고 어떤 API는 바로 배열을 반환하거나, 로그인 성공 시 어떤 곳은 토큰을 주고 어떤 곳은 사용자 객체만 주는 식으로 구조가 흔들립니다. 이렇게 되면 이후 장에서 카탈로그, 인증, 장바구니, 주문 기능을 붙일수록 수정 비용이 계속 커집니다.
그래서 이번 페이지에서는 실제 기능 구현을 본격화하기 전에 아래 세 가지를 먼저 고정합니다.
많은 초급 튜토리얼은 API를 하나 만들고 화면 하나 만들면서 그때그때 응답 구조를 정합니다. 하지만 이번 교재는 DDD 기반 이커머스 서비스를 끝까지 완성하는 흐름입니다. 따라서 API 계약은 기능 뒤에 따라오는 것이 아니라, 기능을 안전하게 붙이기 위한 선행 조건입니다.
특히 이번 프로젝트에서는 아래 이유 때문에 계약을 먼저 맞춰야 합니다.
storefront와 admin이 같은 서버를 본다즉 이번 페이지는 문서 정리용이 아니라, 이후 구현 충돌을 줄이기 위한 구조 정리 단계입니다.
이 페이지를 읽고 나면 아래 항목이 정리되어 있어야 합니다.
공통 API 계약이 없으면 프론트는 각 엔드포인트를 특별 취급하게 됩니다. 그러면 다음 문제가 생깁니다.
이번 교재에서는 "모든 API가 완전히 똑같아야 한다"가 아니라, 최소한 공통 패턴은 있어야 한다는 관점이 중요합니다.
이번 프로젝트에서는 아래와 같은 기준을 먼저 정하는 것이 좋습니다.
예를 들면 성공 응답에서 아래 질문에 답할 수 있어야 합니다.
중요한 것은 개별 API를 예쁘게 만드는 것이 아니라, 프론트가 예측 가능한 방식으로 응답을 읽을 수 있게 하는 것입니다.
이커머스 서비스에서는 목록 응답이 매우 자주 등장합니다.
이때 어떤 API는 배열만 주고, 어떤 API는 페이징 메타를 주고, 어떤 API는 키 이름도 다르면 프론트는 매번 별도 어댑터를 써야 합니다. 따라서 이번 교재에서는 목록 응답의 최소 공통 패턴을 먼저 정하는 것이 좋습니다.
예를 들어 아래 정도를 먼저 합의할 수 있습니다.
itemstotalpagepage_size초기 MVP에서 실제 페이징을 아직 쓰지 않더라도, 확장 방향을 고려한 최소 형식을 생각해 두는 편이 좋습니다.
성공 응답은 화면이 보이면 당장은 넘어갈 수 있습니다. 하지만 오류 응답이 제각각이면 프론트는 실패 상황을 일관되게 처리할 수 없습니다.
예를 들어 아래가 섞이면 문제가 됩니다.
{ detail: ... }를 준다이번 교재에서는 최소한 아래를 공통화해야 합니다.
즉 오류 응답은 단순한 실패 메시지가 아니라, 프론트와 디버깅 흐름을 동시에 지탱하는 계약입니다.
프론트 입장에서 인증 실패는 단순한 일반 오류가 아닙니다. 인증 실패가 발생하면 보통 아래 행동이 뒤따릅니다.
반면 일반 비즈니스 오류는 현재 화면에서 메시지를 보여주고 수정하게 하는 경우가 많습니다. 그래서 이번 교재에서는 인증 실패와 일반 도메인 오류를 응답 구조와 status code 차원에서 분리하는 것이 중요합니다.
모든 타입을 공유 패키지로 옮길 필요는 없습니다. 하지만 아래 타입은 프론트와 백엔드가 다른 말을 하면 곧바로 문제가 됩니다.
이 타입들은 두 앱과 서버가 같은 이름과 같은 상태 값을 보도록 맞추는 편이 좋습니다.
이커머스 도메인에서는 상태 이름 하나가 코드 전반에 퍼집니다.
pendingpaidfailedcancelledcompleted문제는 프론트와 백엔드가 각각 다른 문자열을 쓰기 시작하면, 화면 분기와 필터와 배지가 모두 어긋난다는 점입니다. 따라서 이번 교재에서는 주문 상태, 결제 상태, 인증 상태 같은 핵심 enum 성격의 값은 처음부터 공통 상수나 공통 타입으로 관리하는 편이 좋습니다.
프론트가 API 응답을 해석하는 위치도 중요합니다. 가장 피해야 할 방식은 컴포넌트마다 응답 구조를 직접 뜯는 것입니다.
예를 들어 아래 방식은 좋지 않습니다.
response.data.items를 직접 해석response.items를 해석detail만 읽음이번 교재에서는 최소한 아래 중 하나로 통일하는 편이 좋습니다.
즉 컴포넌트는 가능하면 "이미 해석된 데이터"를 받는 쪽이 낫습니다.
백엔드에서 계약은 단순히 README에 적는 것으로 끝나면 안 됩니다. 실제로는 아래 지점에서 보장되어야 합니다.
즉 백엔드가 계약을 코드 레벨에서 고정하지 않으면, 문서에 있는 규칙은 쉽게 무너집니다.
이번 교재에서 아직 완전한 인증 구현 장으로 들어가지는 않았지만, 골격 단계에서 최소한 아래는 먼저 정해야 합니다.
이 질문에 대한 답이 없으면 다음 장의 카탈로그와 인증 구현에서 프론트와 백엔드가 계속 충돌합니다.
정답은 팀과 환경에 따라 달라질 수 있지만, 이번 교재에서는 최소한 "한 가지 기준을 일관되게 쓰는 것"이 중요합니다.
예를 들어 토큰 기반이라면 아래를 먼저 고정해야 합니다.
세션 쿠키 기반이라면 아래가 중요합니다.
중요한 것은 방식 자체보다, 프론트와 백엔드가 같은 방식으로 구현된다는 점입니다.
같은 로그인이라도 운영자와 구매자는 완전히 같은 권한 모델이 아닙니다. 따라서 아래를 먼저 구분해서 생각해야 합니다.
이 구분이 있어야 admin에서 일반 사용자 세션으로 진입하는 문제를 초기에 막을 수 있습니다.
이번 단계에서 모든 endpoint를 완성할 필요는 없습니다. 하지만 최소한 아래 정도는 표로 나와 있어야 합니다.
GET /productsPOST /auth/loginGET /auth/meGET /admin/ordersGET /health각 항목에 대해 아래를 적으면 충분합니다.
이 표가 있으면 다음 장의 실제 구현과 테스트가 훨씬 수월해집니다.
공유 타입은 유용하지만, 무턱대고 늘리면 오히려 결합이 심해집니다. 이번 교재에서는 아래 원칙이 적절합니다.
즉 공유 타입은 "외부 경계 계약" 중심이어야지, 서버 내부 구현 세부사항까지 끌고 오면 안 됩니다.
이번 페이지를 코드와 문서로 옮기면 최소한 아래 산출물이 있어야 합니다.
이 산출물이 있어야 다음 페이지에서 첫 통합 실행을 할 때 "왜 여기서 깨졌는가"를 훨씬 빨리 파악할 수 있습니다.
이 여섯 가지 실수는 기능이 늘수록 풀스택 개발 속도를 빠르게 떨어뜨립니다.
이 페이지에서 우리는 프론트와 백엔드가 같은 계약을 보도록 성공 응답, 오류 응답, 공통 타입, 상태 이름, 인증 바닥을 먼저 맞추는 이유를 정리했습니다. 또한 API 계약은 문서만이 아니라 response schema, 공통 예외 처리, 프론트 API client 해석 규칙, 테스트까지 포함해 코드로 보장되어야 한다는 점도 확인했습니다.
다음 페이지에서는 지금까지 세운 백엔드 골격, 프론트 골격, API 계약 바닥을 바탕으로 제품 전체를 처음으로 함께 실행하고 smoke test를 진행합니다.