[stock101] 프론트앤드 구조를 잘 만들어야 관리가 쉽다.

2026. 1. 29. 14:55·Archive(완료된 내용)/포트폴리오 강화

 

ai에게 부탁해서 만든 프로젝트는 내가 프롬포트를 잘게 쪼개지 않는이상 다음과같이 한파일에 전부 구현한다. 

 

 

stock_detail.vue

   const loadStock = async (id) => {
        if (!id) return
        try {
    const { data } = await axios.get(`/api/v1/stock/${id}`)

            // 다양한 응답 구조 대응
            let stock = null
            if (Array.isArray(data?.items)) {
                stock = data.items[0]
            } else if (Array.isArray(data)) {
                stock = data[0]
            } else if (data?.item) {
                stock = data.item
            } else {
                stock = data
            }
            stockInfo.value = stock
        } catch (error) {
            console.error('❌ Failed to load stock', error)
        }
}

 

이러면 생기는 문제는 backend에서 응답에 결과를 추가하거나 바꾸면 어디서 단계적으로 접근할지 매번 찾는게 일이다. 

stock_detail 말고 다른곳도 문제있다면 사방 팔방 뛰어댕겨야한다. 

디버그로 오류라도 자세히 알려주면 좋지만 자바에비해 너그러운 언어다보니 찾기 힘들다.  그래서 아래와같이 한다고한다. 리팩토링 작업을 진행해야한다...

 

1. 문제 인지: 왜 JS 환경에서 데이터 관리가 힘든가?

자바스크립트(JS)는 타입에 관대합니다. 서버 API가 변경되어 데이터 필드명이 바뀌거나, 특정 값이 null로 내려와도 실행 전까지는 오류를 알 수 없습니다.

  • Runtime Error: undefined 객체의 속성에 접근할 때 발생하는 TypeError는 서비스 중단의 주범입니다.
  • 유지보수 지옥: API 응답 필드명이 바뀌면, 해당 데이터를 사용하는 모든 컴포넌트 파일을 찾아 일일이 수정해야 합니다.
  • 의사소통 비용: 백엔드 DTO의 암호 같은 필드명(예: stck_oprc)이 프론트엔드 로직에 그대로 노출되면 코드 가독성이 떨어집니다.

2. 해결책: 인터페이스 정의와 데이터 매핑 (Layered Architecture)

이를 해결하기 위해 프론트엔드 내부에 데이터를 정제하는 전용 계층을 둡니다.

① Interface (규격화)

먼저 백엔드 DTO와 일치하는 타입을 정의합니다. TypeScript를 사용하면 가장 좋으며, JS 환경이라면 주석이나 명세서로 관리합니다.

TypeScript
 
// src/types/stock.ts
// 백엔드 StockPriceResponseDto와 1:1 매칭
export interface DailyPrice {
  date: string;     // 날짜 (YYYY-MM-DD)
  open: number;     // 시가
  high: number;     // 고가
  low: number;      // 저가
  close: number;    // 종가
  volume: number;   // 거래량
}

export interface StockPriceResponse {
  stockCode: string;
  stockName: string;
  prices: DailyPrice[];
}

② API Service & Mapper (데이터 정제)

API 호출부에서 데이터를 받아올 때, 컴포넌트로 넘겨주기 전 "매핑(Mapping)" 과정을 거칩니다. 이 단계가 가장 중요합니다.

JavaScript
 
// src/api/stockService.js
import axios from 'axios';

/**
 * 서버의 원본 데이터(Raw Data)를 프론트엔드 규격에 맞게 변환하는 매퍼
 */
const transformStockResponse = (data) => {
  return {
    symbol: data.stockCode,
    name: data.stockName || 'Unknown',
    // 데이터 안정성 확보: prices가 없을 경우 빈 배열로 방어
    dailyList: (data.prices || []).map(p => ({
      date: p.date,
      open: p.open ?? 0,
      high: p.high ?? 0,
      low: p.low ?? 0,
      close: p.close ?? 0,
      volume: p.volume ?? 0
    }))
  };
};

export const getDailyPrices = async (stockCode, days) => {
  const response = await axios.get(`/${stockCode}/prices`, { params: { days } });
  // 호출하는 곳(Component)은 항상 정제된 데이터만 받게 됨
  return transformStockResponse(response.data);
};

3. 실전 폴더 구조 (Best Practice)

효율적인 관리를 위해 프로젝트 구조를 다음과 같이 나눕니다.

폴더명 설명 비고
src/types 데이터 구조 정의 (Interface) 백엔드 DTO와 통일
src/api 통신 로직 및 데이터 매퍼 (Mapper) 에러 발생 시 이곳만 수정
src/views UI 컴포넌트 정제된 데이터 사용에만 집중
src/utils 데이터 포맷터 (금액 콤마, 날짜 변환) 공통 유틸 함수

4. 이 구조가 주는 강력한 이점 

  1. 에러 추적의 단일화: 서버 데이터 키가 바뀌면 api/ 폴더 내의 매핑 함수 한 곳만 고치면 됩니다. (수십 개의 화면 파일을 열어볼 필요가 없습니다.)
  2. 데이터 안전성 (Null Safety): ?? 0이나 || [] 같은 처리를 매퍼에서 미리 해두므로, 컴포넌트에서 undefined 에러로 앱이 뻗는 일을 원천 차단합니다.
  3. 코드 가독성: 컴포넌트 로직에 stckOprc 같은 백엔드 용어 대신 open 같이 직관적인 이름을 사용할 수 있어 비즈니스 로직에만 집중할 수 있습니다.
  4. 테스트 용이성: API 서버가 완성되지 않아도 매퍼가 반환할 가짜 데이터(Mock Data) 구조만 맞춰두면 프론트엔드 개발을 멈추지 않고 진행할 수 있습니다.
저작자표시 비영리 변경금지 (새창열림)

'Archive(완료된 내용) > 포트폴리오 강화' 카테고리의 다른 글

[Stock101] @AuthenticationPrincipal을 활용한 유저 정보 관리  (0) 2026.01.31
[Stock101] 프론트를 재정비하자.- 8일차  (1) 2026.01.29
[Stock101] 반기 / 분기 공시 요약 및 전망 AI 기능 마무리- 8일차  (0) 2026.01.28
[Stock101]PDF 내용 요약 구현 - 7일차  (1) 2026.01.27
[Stock101] RAG PDF내용 요약과 전망을 도출하자 - 6일차  (0) 2026.01.26
'Archive(완료된 내용)/포트폴리오 강화' 카테고리의 다른 글
  • [Stock101] @AuthenticationPrincipal을 활용한 유저 정보 관리
  • [Stock101] 프론트를 재정비하자.- 8일차
  • [Stock101] 반기 / 분기 공시 요약 및 전망 AI 기능 마무리- 8일차
  • [Stock101]PDF 내용 요약 구현 - 7일차
오늘은치킨이닭
오늘은치킨이닭
개발로 세상을 밝히자.(억지 맞음)
  • 오늘은치킨이닭
    개발세밝
    오늘은치킨이닭
  • 전체
    오늘
    어제
    • 분류 전체보기 (80)
      • Project(마감 기한이 정해진 목표) (2)
        • Docker(도커) (1)
        • Django(장고) (0)
        • 부트캠프 (1)
      • Archive(완료된 내용) (59)
        • 재취업준비 (8)
        • 포트폴리오 강화 (24)
        • 부트캠프 (3)
        • 팁 (2)
        • 데이터베이스 (2)
        • SQL (12)
        • 백엔드 (5)
        • 프론트엔드 (1)
        • 유니티(Unity) (2)
      • Area(일생동안 지속 유지하는 활동,마감X) (16)
        • 게임 (2)
        • 코딩테스트 (12)
        • 운영체제 (0)
        • DB (2)
      • Resource(지속적 관심을 갖는 주제분야) (1)
        • 애니메이션 (0)
        • 내가 선정한 맛집 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    명동맛집
    명동
    맛집
    DB #데이터베이스
    고클린 #cpu온도보는법 #cpu온도
    인포그래픽 #자기소개서 #자기소개 #명함삭제
    칼국수맛집
    롤 #룬 #자동적용 #블리츠 #다운로드 #도움 #TIP #브론즈 #아이언 #브실골 #아브실
    명동교자
    유니티 #설치 #방법 #다운
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
오늘은치킨이닭
[stock101] 프론트앤드 구조를 잘 만들어야 관리가 쉽다.
상단으로

티스토리툴바