개발 slecs

광고 슬롯 조회를 빌드타임 정적 데이터로 전환해 런타임 DB 호출 제거

목차

런타임마다 DB를 찌르던 광고 슬롯 조회를 빌드타임 정적 데이터로 내려버린 작업이다.

왜 이 타이밍에 건드렸냐

MobonSlot 컴포넌트가 페이지 렌더링 시점에 매번 DB를 호출하는 구조였다. 광고 슬롯 단위(ad unit) 정보는 사실상 배포 주기 내에서 거의 바뀌지 않는 데이터인데, 요청마다 DB 커넥션을 열고 닫는 게 납득이 안 됐다. 팀 내에서 이미 money 패턴이라고 부르는 선례가 있었다 — 비슷한 성격의 준정적(quasi-static) 데이터를 빌드 스크립트로 긁어서 JSON 파일로 고정해두는 방식. 이번엔 그 패턴을 ads 도메인에 복제한 거다.

기술 부채라기보다 "언젠가 해야 했던 것"에 가까웠는데, 마침 MobonSlot 관련 이슈가 올라오면서 손댈 명분이 생겼다. 팀장 입장에서 이런 기회를 놓치면 또 몇 달 밀린다. 이슈 픽스 겸 구조 개선을 묶어서 처리했음.

변경 구조 한눈에

파일 역할 변경 방향
scripts/sync-ad-units.js 빌드 전 DB → JSON 동기화 스크립트 신규 추가
src/data/ad-units.json 슬롯 단위 정적 스냅샷 신규 생성 (빌드 결과물)
src/components/MobonSlot.astro 실제 슬롯 렌더 컴포넌트 DB 호출 제거, JSON import로 교체
publish.sh 배포 스크립트 sync 스크립트 실행 단계 추가
package.json 스크립트 등록 sync-ad-units 커맨드 추가

핵심은 MobonSlot.astro 쪽이다. 기존엔 컴포넌트 내부에서 런타임 fetch/query가 있었을 텐데, 이제 그냥 JSON을 import해서 쓴다. Astro는 빌드타임에 정적 파일을 번들링하니까 이 흐름이 자연스럽게 맞아떨어진다.

// scripts/sync-ad-units.js 패턴 (개념 예시)
import { writeFileSync } from 'fs';
import { fetchAdUnits } from '../lib/db.js';

const units = await fetchAdUnits();
writeFileSync('src/data/ad-units.json', JSON.stringify(units, null, 2));
// MobonSlot.astro  변경 
import adUnits from '../data/ad-units.json';

const slot = adUnits.find(u => u.id === Astro.props.slotId);

런타임 의존성이 싹 사라진다. 컴포넌트 입장에서는 그냥 로컬 데이터를 읽는 것뿐.

publish.sh에 sync 단계를 끼워넣은 이유

여기서 잠깐 고민이 있었다. sync 스크립트를 CI에서 별도 job으로 뺄 수도 있고, 아니면 publish.sh 안에 순서대로 박아버릴 수도 있다. 후자를 택한 건 단순함 때문이다.

  • 별도 CI job으로 분리하면 파이프라인 의존성 관리가 생긴다
  • publish.sh는 팀이 이미 배포 진입점으로 신뢰하고 있는 파일이다
  • money 패턴이 이미 같은 방식으로 작동하고 있어서, 팀원이 흐름을 파악하기 쉽다

일관성이 가독성이다. 두 개의 패턴이 같은 방식으로 동작하면, 세 번째 사람이 온보딩할 때 하나만 이해해도 나머지를 추론할 수 있다. 이게 팀 코드베이스에서 "패턴 복제"를 의식적으로 선택하는 이유다.

이런 구조 전환에서 항상 확인하는 것들

  • 데이터 변경 주기: 슬롯 단위가 얼마나 자주 바뀌나? 배포보다 잦으면 이 패턴이 오히려 독이다
  • stale 허용 범위: 광고 슬롯은 배포 사이클 내 stale이 허용되는가? 이번 케이스는 그렇다고 판단했다
  • sync 실패 시 fallback: 스크립트가 죽으면 어떻게 되나? 기존 JSON이 남아있으니 빌드는 이전 스냅샷으로 진행된다 — 이건 장점이기도 하다
  • 로컬 개발 환경: 개발자가 sync-ad-units를 실행하지 않으면 JSON이 없거나 낡아있다. 이 부분은 README나 dev 스크립트에 안내가 필요하다

마지막 항목은 코드리뷰 때도 지적했다 — package.jsondev 스크립트에 sync를 prepend로 걸어두면 로컬에서 빠뜨리는 사고를 방지할 수 있다. 작은 거지만 팀원이 "왜 슬롯이 안 뜨지?"로 30분 날리는 걸 막는 게 낫다.


money 패턴이 이미 있었다는 게 이 작업을 빠르게 끝낼 수 있었던 핵심이었다. 좋은 패턴 하나가 코드베이스 전반의 속도를 올린다는 걸 다시 실감했음. 다음엔 비슷한 성격의 데이터가 더 있는지 훑어볼 생각이다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.