3 min read

Next.js App Router 블로그 MVP 설계

App Router 기반 블로그 MVP를 Clean Architecture 관점으로 설계하고, 레이어 책임과 인프라 트레이드오프를 정리한 실무 가이드

Next.js App Router 블로그 MVP 설계 thumbnail

도입

블로그 MVP는 빠르게 출시하는 것이 목표지만, 초기 구조를 잘못 잡으면 기능이 늘어날수록 콘텐츠 처리, SEO, 배포 안정성이 함께 무너진다. App Router는 서버 컴포넌트 중심 개발에 유리하지만, 라우트 파일에 비즈니스 로직이 몰리기 쉬운 구조이기도 하다.

이 글은 App Router 기반 MVP를 Clean Architecture 레이어 분리로 설계해, 출시 속도와 확장 가능성을 동시에 확보하는 방법을 다룬다.

문제 정의

초기 MVP에서 자주 생기는 문제는 다음과 같다.

  • app/** 라우트 파일에 데이터 접근/검증/가공 로직이 섞임
  • SEO 메타데이터 생성 규칙이 페이지마다 분산됨
  • 콘텐츠 파싱 실패가 런타임에서만 드러남
  • 배포 파이프라인은 통과했지만 실제 페이지 데이터가 불완전함

핵심은 "라우팅"과 "유스케이스"를 분리하고, 콘텐츠 모델을 단일 경로로 유지하는 것이다.

개념 설명

MVP에서 필요한 최소 레이어

레이어책임파일 예시
Presentationroute/page 구성, 요청/응답 바인딩app/posts/[slug]/page.tsx
Application유스케이스, 정렬/필터 정책lib/application/get-post-list.ts
Domain포스트 모델, 태그 규칙, 날짜 정책lib/domain/post.ts
Infrastructure파일 읽기, MDX 파싱, 배포 연동lib/posts.ts

MVP 기능 범위

  1. 콘텐츠: content/posts/*.mdx
  2. 라우트: /, /posts, /posts/[slug], /tags, /about
  3. SEO: generateMetadata + sitemap + rss
  4. 검증: 빌드 단계 frontmatter 체크

코드 예시

예시 1: Route Handler에서 유스케이스 호출

import { getPostListUseCase } from "@/lib/application/get-post-list";

export default async function PostsPage() {
  const posts = await getPostListUseCase({
    sortBy: "date_desc",
    limit: 20,
  });

  return <PostList posts={posts} />;
}

예시 2: Application 계층에서 경계 고정

import { postRepository } from "@/lib/infrastructure/post-repository";

type Params = {
  sortBy: "date_desc" | "date_asc";
  limit: number;
};

export async function getPostListUseCase(params: Params) {
  const items = await postRepository.findAll();
  const sorted = [...items].sort((a, b) =>
    params.sortBy === "date_desc"
      ? new Date(b.date).getTime() - new Date(a.date).getTime()
      : new Date(a.date).getTime() - new Date(b.date).getTime(),
  );

  return sorted.slice(0, params.limit);
}

아키텍처 설명

App Router MVP에서는 요청 흐름과 콘텐츠 흐름을 별도로 보아야 한다.

Mermaid diagram rendering...

Clean Architecture 레이어 구조

실무에서 유지보수 가능한 MVP를 만들려면 아래 경계를 명확히 유지해야 한다.

  • Presentation: 라우팅, 사용자 입력 바인딩, 페이지 단위 조합
  • Application: 유스케이스 오케스트레이션, 정렬/필터링 정책
  • Domain: 핵심 규칙(태그/날짜/slug 정책), 타입 불변성
  • Infrastructure: 파일 시스템 접근, MDX 파싱, 외부 플랫폼 연동

인프라 구성도

Mermaid diagram rendering...

트레이드오프 분석

선택장점단점권장 상황
라우트 중심 단일 구현빠른 초기 개발책임 혼재, 테스트 어려움단기 데모
Clean Architecture 분리변경 내성 높음, 테스트 용이초기 구조 비용 증가운영 예정 MVP
정적 생성 극대화성능/비용 유리실시간성 제한콘텐츠 중심 서비스
동적 렌더링 혼합실시간 반영 유리캐시/비용 관리 필요빈번한 데이터 변동

MVP 단계에서는 "너무 많은 추상화"도 위험하지만, 경계 없이 시작하는 것 역시 확장 비용을 키운다. 최소 레이어를 먼저 정의하고, 필요할 때만 확장하는 방식이 가장 실용적이다.

정리

App Router 블로그 MVP의 핵심은 기능 목록보다 경계 설계다. 아래 세 가지를 우선 고정하면 이후 기능 추가가 훨씬 안전해진다.

  • 라우트는 조합만 담당하고 유스케이스는 별도 계층에 둔다.
  • 콘텐츠 모델은 단일 검증 경로로 관리한다.
  • metadata/sitemap/rss 생성은 같은 데이터 소스를 사용한다.

이 원칙을 지키면 MVP 이후 검색, 태그, 분석, 추천 기능을 붙여도 구조가 쉽게 흔들리지 않는다.

함께 읽기

댓글