백엔드에 명령하는 프론트엔드가 되어보자

타락한스벨트전도사·2025년 7월 11일
112
post-thumbnail

백엔드 눈치 보는 프론트엔드의 현실

"API 언제 나와요?"

회사든 사이드프로젝트든, 프론트엔드 개발자라면 한 번쯤 해봤을 질문입니다. 백엔드 개발자에게 눈치를 주며 물어보지만, 돌아오는 답변은 늘 "조금만 더 기다려주세요"입니다.

그렇다고 손 놓고 있을 수는 없죠. 일정은 촉박하고, 화면은 그려야 하니까 임시로 하드코딩된 데이터를 넣어서 개발을 시작합니다.

// 이런 식으로 임시 데이터 넣고 개발하죠...
const posts = [
  { id: 1, title: "임시 게시글 1", content: "임시 내용..." },
  { id: 2, title: "임시 게시글 2", content: "임시 내용..." },
];

그런데 문제는 여기서 시작됩니다.

게시판을 만든다고 생각해보세요. 게시글 목록, 상세 보기, 댓글, 좋아요, 페이징... 이 모든 기능들이 백엔드 API와 연동되어야 제대로 동작하는지 확인할 수 있습니다.

임시 데이터로는 한계가 있어요:

  • 페이징이 제대로 작동하는지 모름
  • 댓글 등록/삭제가 실제로 반영되는지 확인 불가
  • 로딩 상태나 에러 처리 테스트 어려움

결국 백엔드 API가 나올 때까지 기다리다가, 일정 마감 직전에 모든 걸 한 번에 연동하게 됩니다. 그리고는 예상치 못한 버그들과 마주하며 밤을 새우게 되죠. 마감 못 지키면? 당연히 프론트엔드가 다 떠안습니다.

"백엔드는 API 다 만들었는데, 프론트엔드가 연동을 못 했네요." 이런 소리 들어본 적 있지 않나요? 진짜 개같죠.

더 짜증나는 건, API 스펙이 예상과 달라서 임시로 만들어놨던 코드를 다시 뜯어고쳐야 할 때입니다. "아 이거 다시 해야 해?" 하면서 중복 작업에 시달리게 됩니다.

이런 악순환, 이제 그만 끝내고 싶지 않나요?

오늘 소개할 방법을 사용하면, 더 이상 백엔드 개발자에게 눈치 주지 않아도 됩니다. 오히려 여러분이 먼저 화면을 완성해서 보여주고, "이대로 API 만들어주세요"라고 말할 수 있게 될 거예요.

나는 페이지 자체를 스토리북으로 구현한다

스토리북(Storybook) 들어보셨나요? 보통은 버튼, 카드 같은 UI 컴포넌트 문서 만드는 도구 정도로 알려져 있어요.

https://storybook.js.org/

하지만 저는 완전히 다르게 사용합니다.

컴포넌트가 아닌 페이지 전체를 스토리북에 올려요. 실제 서비스 화면을 그대로 스토리북에서 구현하는 거죠.

실제 예시: 게시판 서비스

간단한 게시판을 예로 들어보겠습니다. 게시글 작성, 댓글 달기, 좋아요 기능이 있는 일반적인 게시판이에요.

https://fe-resume.coach

보시다시피 실제 서비스와 똑같이 동작합니다.

  • 게시글 작성하고
  • 댓글 달고 삭제하고
  • 좋아요 버튼 누르면 숫자 증가하고
  • 페이지네이션도 자연스럽게 되고

"어? 이거 백엔드 API 없이 어떻게 동작하는 거지?"

바로 여기서 핵심이 나옵니다. 모든 API를 Mock으로 구현했거든요.

이렇게 하면 뭐가 좋은데?

1. 백엔드 기다릴 필요 없음
더 이상 "API 언제 나와요?" 묻지 않아도 됩니다. 제가 먼저 Mock API로 모든 기능을 구현해놓고, 백엔드 개발자에게 "이대로 만들어주세요"라고 말할 수 있어요.

2. 복잡한 시나리오도 쉽게 테스트

평소에 디자인 한 번 수정하고 확인할 때마다 얼마나 귀찮았나요?

  • 결제 페이지 확인하려면: 로그인 → 상품 선택 → 장바구니 → 결제 정보 입력 → ...
  • 로그인 필수 페이지 확인하려면: 매번 로그인하고 → 해당 메뉴 찾아서 클릭하고 → ...
  • 에러 상태 확인하려면: 일부러 잘못된 데이터 입력하고 → 에러 발생시키고 → ...

이제는 스토리북에서 상태별로 페이지들을 한 번에 볼 수 있어요:

  • 결제 완료 상태
  • 결제 실패 상태
  • 로딩 중 상태
  • 네트워크 에러 상태
  • 빈 데이터 상태

클릭 한 번으로 모든 상황을 바로 확인할 수 있습니다. 짱 쉽죠?

3. 디자이너/기획자와 소통 편함
스토리북 링크 하나만 보내주면 됩니다. "이 페이지에서 이 버튼 눌러보세요" 하면서 실제로 체험해볼 수 있어요.

핵심은 Mock/Real API 쉬운 전환

이런 걸 가능하게 만드는 핵심은 환경에 따라 Mock과 Real API를 쉽게 전환할 수 있는 구조입니다.

// package.json
{
  "imports": {
    "#api": {
      "storybook": "./lib/api/mock/index.ts",
      "default": "./lib/api/client/index.ts"
    }
  }
}

개발할 때는 Mock API 쓰고, 프로덕션에서는 Real API 쓰는 거죠. 코드 한 줄 바꾸지 않고 말이에요.

// 환경에 따라 자동으로 Mock/Real 매칭
import { postService } from "#api";

이제 더 이상 백엔드 기다리지 마세요.
npm run storybook 켜고 Mock API로 모든 기능을 완성한 다음, 백엔드가 준비되면 import 개발모드를 켜서 확인해보면 됩니다.

프론트엔드가 주도하는 개발

이 방식을 사용하면서 겪은 실제 경험들을 공유해드릴게요.

경험 1: 외주사에서 영웅되기

상황: 블록체인 프로젝트 외주를 받았는데, 프론트엔드만 담당하게 되었어요. 스마트 컨트랙트(백엔드라고 생각하시면 됩니다)는 외주사 팀에서 개발 중이었고요.

문제: 막상 개발 시작하려니 컨트랙트가 아직 배포 안 되어 있더라고요.

기존 방식이었다면:

  • "컨트랙트 배포 언제 되나요?"
  • "일단 기다리겠습니다..."
  • 마지막에 부랴부랴 연동하다가 시연에서 동작 안 함 💥

제가 한 방식:

1주차: Mock 컨트랙트로 모든 화면 완성 (스토리북)
2주차: 클라이언트 시연 → "와 벌써 다 됐네요!"
3주차: 실제 컨트랙트 배포됨
4주차: 파일 한두 개만 교체해서 연동 완료 ✨

Mock 컨트랙트 예시:

// lib/api/mock/contract.ts
export class TokenContract {
  async getBalance(address: string): Promise<string> {
    // 가짜 잔액 반환
    return "1,234.56 ETH";
  }

  async transfer(to: string, amount: string): Promise<string> {
    // 가짜 트랜잭션 해시 반환
    await new Promise((resolve) => setTimeout(resolve, 2000)); // 로딩 시뮬레이션
    return "0x123abc...";
  }
}

결과:

  • 클라이언트: "다른 팀은 컨트랙트 기다린다고 지연되는데, 이 팀은 벌써 다 완성했네?"
  • 외주사 팀: "어떻게 컨트랙트 없이 이렇게 완벽하게 동작하지?"
  • 나: 파일 한두 개만 바꿔서 실제 컨트랙트 연동 완료 → 영웅 등극 ✨

시연할 때 지갑 연결, 토큰 전송, 잔액 조회 모든 기능이 실제처럼 동작하니까 임팩트가 완전 달랐어요. "아직 컨트랙트 연동은 안 됐지만..."이 아니라 "이미 다 완성됐습니다!"라고 말할 수 있었거든요.

경험 2: 사이드프로젝트에서 백엔드에게 명령하기

상황: 팀원 4명 (기획 1, 디자인 1, 프론트 1(나), 백엔드 1) 사이드프로젝트

기존 방식:

  1. 기획서 작성
  2. 백엔드가 API 설계 고민
  3. 프론트는 기다리기
  4. API 나오면 연동하면서 "어? 이건 이렇게 나와야 하는데..."
  5. 수정 요청 → 다시 기다리기 → 무한 반복

제가 바꾼 방식:

  1. 기획서 받자마자 Mock API로 전체 서비스 구현
  2. 스토리북 링크 공유: "이렇게 동작해야 합니다"
  3. 백엔드팀원에게: "이 API 스펙대로 만들어주세요" (명령 톤 ㅋㅋ)
// 백엔드팀원에게 전달한 API 스펙
interface UserAPI {
  // GET /api/users/me
  getMe(): Promise<{
    id: string;
    nickname: string;
    profileImage: string;
    point: number; // 바로 이 필드가 필요해요!
  }>;

  // POST /api/posts
  createPost(data: {
    title: string;
    content: string;
    images: string[]; // 이미지 URL 배열로 주세요
  }): Promise<{ id: string }>;
}

백엔드팀원 반응:

  • "어? 벌써 화면 다 나왔네? 신기하다"
  • "API 스펙 고민할 필요 없이 그대로 만들면 되겠네"
  • "프론트에서 필요한 데이터가 뭔지 명확하니까 개발하기 편하다"

경험 3: 디자이너와의 소통이 편해짐

Before:

  • 디자이너: "이 버튼 색깔 좀 바꿔주세요"
  • 나: "네, 수정해서 스테이징 서버에 배포할게요"
  • 문제: 스테이징 서버가 없어요... 😅
  • 결국 "나중에 확인해주세요" → 소통 단절

After:

  • 디자이너: "이 버튼 색깔 좀 바꿔주세요"
  • 나: 스토리북 수정 → Chromatic으로 바로 배포 (2분 소요)
  • 나: "링크 보내드릴게요, 이렇게 동작할 거예요" 📱
  • 디자이너: "아 이런 느낌이군요! 좋아요!" 👍

Chromatic 배포의 장점:

# 명령어 한 줄이면 끝
npx chromatic --project-token=xxx
  • 별도 서버 구축 필요 없음
  • 모든 상태별 화면 한 번에 공유 가능
  • 모바일/데스크톱 모두 확인 가능
  • URL 하나로 모든 페이지 접근

디자이너가 실제로 클릭하고 체험할 수 있는 링크를 바로 공유하니까 소통이 완전 달라졌어요. "이렇게 될 예정입니다"가 아니라 "지금 당장 확인해보세요!"

결론 - 이제 백엔드에게 명령하세요

"API 언제 나와요?"

"이 스펙대로 만들어주세요!"

Mock API + 스토리북으로 완성된 화면을 보여주면서 당당하게 말할 수 있어요.

더 이상 을(乙)이 아닌, 갑(甲) 포지션의 프론트엔드 개발자가 되어보세요!

프론트엔드가 주도하는 개발의 장점

1. 일정 주도권 확보
더 이상 백엔드 일정에 종속되지 않음

2. 클라이언트/팀원들에게 신뢰 확보
"이 사람은 일을 빠르게 해내는구나"

3. 백엔드와의 관계 개선
명확한 스펙 제공으로 서로 편해짐

4. 품질 향상
미리 모든 케이스를 검토하고 완성도 높은 결과물


실제 프로젝트 소개

현재 저는 AI 이력서 코칭 서비스를 만들고 있습니다!

🔗 https://fe-resume.coach?utm_source=blog&utm_medium=article&utm_campaign=storybook_guide

앞서 보여드린 게시판 예제도 바로 이 프로젝트에요. 마찬가지로 스토리북으로 화면 먼저 완성하고, 백엔드는 뒤에서 작업하고 있답니다.

  • ✅ 이력서 업로드 및 AI 분석
  • ✅ 개인화된 피드백 제공
  • ✅ 이력서 템플릿 추천
  • ✅ 진행상황 추적

여러분도 이런 방식으로 개발해보세요!

백엔드 기다리지 말고, Mock API + 스토리북으로 먼저 완성해서 보여주는 거예요. 정말 개발 경험이 달라질 거예요.

많은 관심 부탁드립니다! ㅎㅎ

profile
기부하면 코드 드려요

12개의 댓글

comment-user-thumbnail
2025년 7월 18일

프로젝트 마감이 오늘인데 프론트 팀원이 임시 데이터로만 개발해서 오류 고치느라 어제 오늘 밤을 새우면서 개발 했습니다. (안타깝게도 완성 못했습니다 ㅠㅠ) 마감도 못지키고 너무 문제 인 것 같아 해결책이 없나 싶었는데 이런 방법이 있었군요. 빨리 적용해봐야겠습니다. 좋은 정보 공유 감사합니다.

답글 달기
comment-user-thumbnail
2025년 7월 18일

재밌네요. API가 완성되기 전에 Mock API를 사용하는 거는 이미 사용중이었는데
Storybook으로 페이지 전체를 만들어서 Staging 서버처럼 사용하는 것은 신기한 거 같습니다.
사이드 프로젝트에서 Staging 서버가 없어서 답답했는데 실천 해봐야겠습니다.

답글 달기
comment-user-thumbnail
2025년 7월 20일

오호 ,,,, 이러면 개인도 스테이징 서버로 활용할 수 있겠네요 ..

답글 달기
comment-user-thumbnail
2025년 7월 21일

정말 좋은 글이에요. 정말 필요했던 글이었어요. 간결한 설명이 참 좋네요. paybyplatema

답글 달기
comment-user-thumbnail
2025년 7월 22일

이렇게 해주시면 백엔드도 너무 좋습니다..

답글 달기
comment-user-thumbnail
2025년 7월 24일

기름진 케밥부터 고급스러운 파이까지, Scrandle 에서는 온갖 종류의 경기장 음식을 제공합니다. 최고의 음식을 골라보세요. 연속 기록을 세우고, 오늘의 승리를 거머쥐세요.

답글 달기
comment-user-thumbnail
2025년 7월 24일

스벨트 5이신가요?

1개의 답글
comment-user-thumbnail
2025년 8월 31일

https://ssgoi.dev
https://ssgoi.dev/en
https://ssgoi.dev/en/docs/getting-started/.introduction
https://ssgoi.dev/en/docs/getting-started/.quick-start
https://ssgoi.dev/en/docs/core-concepts/.element-transitions
https://ssgoi.dev/en/docs/core-concepts/.spring-presets
https://ssgoi.dev/en/docs/view-transitions/fade
https://ssgoi.dev/en/docs/view-transitions/scroll
https://ssgoi.dev/en/docs/view-transitions/hero
https://ssgoi.dev/en/docs/view-transitions/pinterest
https://ssgoi.dev/en/docs/view-transitions/slide
https://ssgoi.dev/en/docs/view-transitions/blind
https://ssgoi.dev/en/docs/view-transitions/drill
https://ssgoi.dev/en/docs/transitions/fade
https://ssgoi.dev/en/docs/transitions/scale
https://ssgoi.dev/en/docs/transitions/blur
https://ssgoi.dev/en/docs/transitions/slide
https://ssgoi.dev/en/docs/transitions/fly
https://ssgoi.dev/en/docs/transitions/rotate
https://ssgoi.dev/en/docs/transitions/bounce
https://ssgoi.dev/en/docs/transitions/mask
https://ssgoi.dev/en/blog
https://ssgoi.dev/en/blog/view-transitions-types
https://ssgoi.dev/en/blog/vue-support
https://ssgoi.dev/en/blog/ssr-optimization
https://ssgoi.dev/en/blog/why-need-animation
https://ssgoi.dev/en/blog/how-to-make-transition
https://ssgoi.dev/en/blog/physics_animation
https://ssgoi.dev/en/blog/what-is-ssgoi
https://ssgoi.dev/ko
https://ssgoi.dev/ko/docs/getting-started/.introduction
https://ssgoi.dev/ko/docs/getting-started/.quick-start
https://ssgoi.dev/ko/docs/core-concepts/.element-transitions
https://ssgoi.dev/ko/docs/core-concepts/.spring-presets
https://ssgoi.dev/ko/docs/view-transitions/fade
https://ssgoi.dev/ko/docs/view-transitions/scroll
https://ssgoi.dev/ko/docs/view-transitions/hero
https://ssgoi.dev/ko/docs/view-transitions/pinterest
https://ssgoi.dev/ko/docs/view-transitions/slide
https://ssgoi.dev/ko/docs/view-transitions/blind
https://ssgoi.dev/ko/docs/view-transitions/drill
https://ssgoi.dev/ko/docs/transitions/fade
https://ssgoi.dev/ko/docs/transitions/scale
https://ssgoi.dev/ko/docs/transitions/blur
https://ssgoi.dev/ko/docs/transitions/slide
https://ssgoi.dev/ko/docs/transitions/fly
https://ssgoi.dev/ko/docs/transitions/rotate
https://ssgoi.dev/ko/docs/transitions/bounce
https://ssgoi.dev/ko/docs/transitions/mask
https://ssgoi.dev/ko/blog
https://ssgoi.dev/ko/blog/view-transitions-types
https://ssgoi.dev/ko/blog/vue-support
https://ssgoi.dev/ko/blog/ssr-optimization
https://ssgoi.dev/ko/blog/why-need-animation
https://ssgoi.dev/ko/blog/how-to-make-transition
https://ssgoi.dev/ko/blog/physics_animation
https://ssgoi.dev/ko/blog/what-is-ssgoi
https://ssgoi.dev/zh
https://ssgoi.dev/zh/docs/getting-started/.introduction
https://ssgoi.dev/zh/docs/getting-started/.quick-start
https://ssgoi.dev/zh/docs/core-concepts/.element-transitions
https://ssgoi.dev/zh/docs/core-concepts/.spring-presets
https://ssgoi.dev/zh/docs/view-transitions/fade
https://ssgoi.dev/zh/docs/view-transitions/scroll
https://ssgoi.dev/zh/docs/view-transitions/hero
https://ssgoi.dev/zh/docs/view-transitions/pinterest
https://ssgoi.dev/zh/docs/view-transitions/slide
https://ssgoi.dev/zh/docs/view-transitions/blind
https://ssgoi.dev/zh/docs/view-transitions/drill
https://ssgoi.dev/zh/docs/transitions/fade
https://ssgoi.dev/zh/docs/transitions/scale
https://ssgoi.dev/zh/docs/transitions/blur
https://ssgoi.dev/zh/docs/transitions/slide
https://ssgoi.dev/zh/docs/transitions/fly
https://ssgoi.dev/zh/docs/transitions/rotate
https://ssgoi.dev/zh/docs/transitions/bounce
https://ssgoi.dev/zh/docs/transitions/mask
https://ssgoi.dev/zh/blog
https://ssgoi.dev/zh/blog/view-transitions-types
https://ssgoi.dev/zh/blog/vue-support
https://ssgoi.dev/zh/blog/ssr-optimization
https://ssgoi.dev/zh/blog/why-need-animation
https://ssgoi.dev/zh/blog/how-to-make-transition
https://ssgoi.dev/zh/blog/physics_animation
https://ssgoi.dev/zh/blog/what-is-ssgoi
https://ssgoi.dev/ja
https://ssgoi.dev/ja/docs/getting-started/.introduction
https://ssgoi.dev/ja/docs/getting-started/.quick-start
https://ssgoi.dev/ja/docs/core-concepts/.element-transitions
https://ssgoi.dev/ja/docs/core-concepts/.spring-presets
https://ssgoi.dev/ja/docs/view-transitions/fade
https://ssgoi.dev/ja/docs/view-transitions/scroll
https://ssgoi.dev/ja/docs/view-transitions/hero
https://ssgoi.dev/ja/docs/view-transitions/pinterest
https://ssgoi.dev/ja/docs/view-transitions/slide
https://ssgoi.dev/ja/docs/view-transitions/blind
https://ssgoi.dev/ja/docs/view-transitions/drill
https://ssgoi.dev/ja/docs/transitions/fade
https://ssgoi.dev/ja/docs/transitions/scale
https://ssgoi.dev/ja/docs/transitions/blur
https://ssgoi.dev/ja/docs/transitions/slide
https://ssgoi.dev/ja/docs/transitions/fly
https://ssgoi.dev/ja/docs/transitions/rotate
https://ssgoi.dev/ja/docs/transitions/bounce
https://ssgoi.dev/ja/docs/transitions/mask
https://ssgoi.dev/ja/blog
https://ssgoi.dev/ja/blog/view-transitions-types
https://ssgoi.dev/ja/blog/vue-support
https://ssgoi.dev/ja/blog/ssr-optimization
https://ssgoi.dev/ja/blog/why-need-animation
https://ssgoi.dev/ja/blog/how-to-make-transition
https://ssgoi.dev/ja/blog/physics_animation
https://ssgoi.dev/ja/blog/what-is-ssgoi

답글 달기
comment-user-thumbnail
2025년 9월 5일

Great post—this was much needed. I really appreciate your clear and straightforward style of explanation. https://paybyplatema.cloud/

답글 달기

asdf

답글 달기
comment-user-thumbnail
2025년 9월 9일

Through our premium Gurgaon Escort Service, we deliver elite companionship that reflects class and refinement. Every booking comes with complete confidentiality and attention to detail. Our agency ensures your comfort and desires are always placed at the highest priority.

답글 달기