Feature Sliced Design + Next.js + Open api generator

h.Im·2025년 5월 9일

회고록

목록 보기
5/5

Open api generator를 사용하는 Next.js 프로젝트에서 Feature Sliced Design을 적용한 사례를 남기는 회고록

Feature Sliced Design 이란?

Layers는 FSD 패턴의 첫 번째 수준을 나타냅니다. 레이어는 각각이 다루어야 할 책임과 다른 모듈과의 의존도에 따라 분류됩니다.

각 Layer는 Slice와 Segment들로 세분화되며, app과 shared 레이어는 그 자체로서 Slice이기 때문에 예외입니다.

상위 레벨에 있는 레이어는 하위 레벨을 의존성으로 가질 수 있지만 그 반대는 성립될 수 없습니다.

하위 레이어일수록 추상화가 심화되며(특정 상황에 국한되지 않는 범용성 높은 작업만을 포함), 상위 레이어일수록 비즈니스 로직이 심화됩니다.

💡 레이어에 대한 가져오기 규칙

레이어 간 가져오기 규칙이 정의되어 있는 이유는 FSD 패턴이 포함 관계를 구체화하는 패턴이기 떄문입니다.

레이어는 매우 응집력 있는 모듈 그룹인 슬라이스로 구성되어 있습니다.
슬라이스의 모듈(파일)은 아래 레이어에 위치하는 것들만 의존성으로 가질 수 있습니다.

For example, the folder 📁 ~/features/aaa is a slice with the name "aaa". A file inside of it, ~/features/aaa/api/request.ts, cannot import code from any file in 📁 ~/features/bbb, but can import code from 📁 ~/entities and 📁 ~/shared, as well as any sibling code from 📁 ~/features/aaa, for example, ~/features/aaa/lib/cache.ts.

이제 하위 레이어에서부터 각각을 알아보고 프로젝트에 어떻게 적용하였는지 알아보겠습니다.


Shared

Shared는 다른 모든 레이어의 근간을 형성하며, Slice를 두지 않고 Segment가 바로 하위에 존재합니다.

일반적으로 Shared가 포함하는 세그먼트는 다음과 같습니다.

  • 📁 api : API 클라이언트이며 특정 백엔드 엔드포인트에 요청을 하는 기능을 포함할 수 있습니다.
  • 📁 ui : 애플리케이션의 ui Kit을 포함합니다. 비즈니스 로직을 포함하는 코드는 존재해선 안되며, 비즈니스 기반으로 분류하는 것은 괜찮습니다. Atomic Design 기준 Atoms 컴포넌트가 포함될 수 있습니다.
  • 📁 lib : 내부 라이브러리 모음. 이 세그먼트를 helper나 utilities 같은 뭉둥그려진 구조로 사용해서는 안되며, 날짜나 색상 같은 특정한 목적별로 관리되어야 합니다.
  • 📁 config : 환경 변수 등 전역 configuration이 포함됩니다.
  • 📁 routes : 라우팅 관련 constants나 pattern 등을 포함할 수 있습니다.
  • 📁 store : 프로젝트 전반에 걸쳐 사용할 Zustand store를 포함할 수 있습니다.

Entities

엔터티 레이어에 포함되는 슬라이스는 실제 다루고자 하는 이 세상의 개념을 포함합니다. 코문철 기준으로, 리뷰/배틀/댓글 등 도메인이 해당됩니다.

아래는 코문철 Entities 레이어 캡처입니다.

업로드중..

각 슬라이스에는 아래 세그먼트들이 포함됩니다.

파일역할
types.ts타입 정의 (인터페이스, enum 등)
model.ts데이터 변환 및 비즈니스 로직
api.tsAPI 호출 관련 함수

types.ts

open api generator를 사용하지 않는 경우, api in/out 타입을 types.ts에 작성해야 합니다. 하지만 api in/out 스펙은 자동 생성되므로

  • 프론트엔드에서 추가로 사용할 비즈니스 로직 관련 타입
  • API 데이터를 가공한 후 상태 관리에 사용할 타입

등이 있다면 이곳에 작성합니다.

💡 open api generator로 자동 생성된 api in/out dto interface는 프로젝트 root/generate 하위에 자동 생성되지만, entites/domain/types.ts에 작성한 것으로 간주하여 의존 관계를 관리하도록 하였습니다.

model.ts

이 파일은 실제 데이터를 다루는 로직을 포함합니다.

주요 역할은:

  • API 데이터와 내부 데이터 모델을 변환 (types.ts에서 정의한 타입 사용)
  • 도메인 로직 포함 (예: 데이터 변환, 기본값 설정 등)

api.ts

이 파일은 엔터티와 관련된 API를 호출하는 함수를 포함합니다.

코문철에서는 open api generator로 자동 생성된 스펙을 호출하면서

  • basePath 설정
  • api 호출 시 공통 apiClient를 경유하도록 설정
  • output 형식 정제

위 세가지 설정을 추가하였습니다.


Features

Features 레이어가 Entities, Shared와 어떻게 다른지 표로 나타내었습니다.

폴더역할
entities/도메인 모델 (User, Comment, Battle 등 핵심 개념)
feature/도메인 단위의 비즈니스 로직과 UI (BattlePage, UserProfile 등)
shared/전역적으로 사용되는 공통 모듈 (UI, Utils, API 클라이언트 등)

이 레이어는 앱의 주요 상호 작용을 포함합니다. 각 도메인에서 다루어야 할 기능을 담지만, “모든 것을 기능으로 세분화”하는 상황을 경계하면 되겠습니다.

코문철의 Feature layer는 Entities layer와 동일하게 도메인 별 Slice를 갖도록 하고, 아래 Segment 들을 갖도록 하였습니다.

파일역할
model/상태 관리 (Zustand)
ui/ui 컴포넌트
hooks/React Hooks
types.ts타입 정의
helper.ts유틸리티 함수
constants.ts상수 정의

0개의 댓글