CAF 소개: 클린 아키텍처 프론트엔드

발행: (2026년 2월 21일 오후 10:52 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

비즈니스 로직을 한 번만 작성하세요. React, Vue, Angular 혹은 다음 프레임워크에서 실행하세요. CAF (Clean Architecture Frontend)는 프레임워크에 구애받지 않는 코어를 제공하는 라이브러리로, 동일한 도메인과 유스케이스를 어댑터를 교체함으로써 모든 프론트엔드에서 실행할 수 있게 합니다.

프론트엔드 애플리케이션은 UI, 상태, 비즈니스 규칙을 혼합하는 경우가 많습니다. 프레임워크를 전환하거나 React, Vue, Angular 간에 로직을 공유해야 할 때, 보통 많은 코드를 다시 작성하게 됩니다. 클린 아키텍처가 도움이 되지만, 단일 프레임워크에 구애받지 않는 코어로 이를 잘 구현하는 것은 어렵습니다. CAF는 그 코어를 제공합니다: 프리미티브와 인터페이스를 통해 도메인과 유스케이스가 프레임워크에 얽매이지 않게 합니다.

CAF는 클린 아키텍처를 활용한 프론트엔드 구축을 위한 프레임워크에 구애받지 않는 코어입니다. 도메인 및 애플리케이션 레이어를 한 번 구현하면, React, Vue, Angular(및 향후 프레임워크)에서 작은 어댑터 패키지를 통해 연결됩니다. 단일 UI 스택에 종속되지 않습니다.

In short

  • Framework‑agnostic – 하나의 코어, 다수의 UI.
  • Clean Architecture – 도메인, 애플리케이션, 인프라스트럭처 레이어가 명확함.
  • Reactive primitives – 단일 리액티브 엔진(Pulse)과 프레젠테이션 로직을 위한 Ploc.
  • Pluggable adapters – 라우팅, HTTP, UI가 인터페이스이며, 여러분(또는 생태계)이 구현합니다.
  • TypeScript‑first – 타입이 지정된 UseCase, RequestResult, 그리고 Ploc를 엔드‑투‑엔드로 사용.

핵심 개념

Pulse

단일 반응형 값(ref와 유사). 하나의 상태 조각(예: 로딩 플래그, 현재 사용자)을 위해 사용합니다.

Ploc

Presentation Logic ComponentPulse를 기반으로 한 상태ful 블록. UI와 관련된 상태와 메서드를 보유합니다.

UseCase

애플리케이션 작업(명령 또는 쿼리)입니다. RequestResult(loading, data, error)를 반환하여 UI가 로딩/오류/성공을 표시할 수 있게 합니다.

RouteRepository

라우팅에 대한 추상화. 앱이 이를 구현합니다(예: React Router 또는 Vue Router). RouteManager는 인증 및 네비게이션에 이를 사용합니다.

도메인 및 애플리케이션 코드는 오직 이러한 추상화에만 의존합니다. 인프라스트럭처(HTTP, 라우팅, 스토리지)와 UI 레이어는 프레임워크에 의존하지만, 코어는 그렇지 않습니다.

시작하기

1. CAFProvider 로 앱 연결하기

// main.tsx or App.tsx
import { CAFProvider } from '@c-a-f/infrastructure-react';
import { setupUserPloc } from './caf/setup';

const userPloc = setupUserPloc();

export default function App() {
  return (
    <CAFProvider>
      {/* Your app UI goes here */}
    </CAFProvider>
  );
}

2. 컴포넌트에서 Ploc 사용하기

import { usePlocFromContext, usePloc } from '@c-a-f/infrastructure-react';
import type { UserPloc } from '../caf/application';

export function UserList() {
  const ploc = usePlocFromContext('user');
  if (!ploc) return null;

  const [state] = usePloc(ploc);

  return (
    <div>
      {state.loading && <p>Loading...</p>}
      {state.error && <p>Error: {state.error}</p>}

      <button onClick={() => ploc.loadUsers()} disabled={state.loading}>
        Refresh
      </button>

      <ul>
        {state.users.map((u) => (
          <li key={u.id}>
            {u.name} – {u.email}
          </li>
        ))}
      </ul>
    </div>
  );
}

동일한 UserPloc와 사용 사례는 Vue 또는 Angular UI를 구동할 수 있습니다; 변경되는 것은 훅(또는 컴포저블/인젝터)뿐입니다.

리포지토리 구조

CAF 리포지토리는 다음 패키지들을 포함하는 모노레포입니다:

  • Core: @c-a-f/coreUseCase, Ploc, Pulse, ApiRequest, RouteManager, 그리고 공유 인터페이스.
  • Infrastructure (adapters):
    • @c-a-f/infrastructure-react – React 훅(usePloc, useUseCase, CAFProvider, useRouteManager, useRouteRepository).
    • @c-a-f/infrastructure-vue – Vue 컴포저블 및 프로바이더.
    • @c-a-f/infrastructure-angular – Angular 서비스 및 인젝터.
  • Optional modules: 검증(@c-a-f/validation), 워크플로, 권한, i18n, 테스트, devtools, CLI 스캐폴딩 등.

예시

  • example-react
  • example-vue
  • example-angular
  • example-vue-graphql
  • example-angular-websocket

각 예시는 자체 caf/ 폴더(도메인, 애플리케이션, 인프라스트럭처)를 포함하고 있으며, 이를 프로젝트에 복사하여 사용할 수 있습니다.

대상 독자

  • : 단일 도메인/애플리케이션 레이어를 원하고 React, Vue, Angular 중 하나로 배포할 수 있는 유연성을 원하는 경우.
  • 개발자: 테스트 가능성과 명확한 경계(도메인 vs. 애플리케이션 vs. 인프라스트럭처)를 중시하는 경우.
  • 모든 사람: 프레임워크‑특정 “클린 아키텍처” 레시피에 지치고, 작은 공유 코어와 관례를 찾는 경우.

설치

npm install @c-a-f/core
npm install @c-a-f/infrastructure-react   # or -vue, -angular

선택 사항: 프로젝트 스캐폴드

npm install -g @c-a-f/cli
caf-init

그런 다음 caf/ 폴더를 만들고 domain/, application/, infrastructure/ 디렉터리를 포함시키며, 레포지토리, 유스케이스, Ploc을 연결하는 설정을 합니다. 레포지토리의 문서와 README에는 정확한 레이아웃과 최소 흐름(예: GetUsers UseCase → Ploc → React/Vue/Angular UI)에 대한 안내가 포함되어 있습니다.

링크

  • GitHub:
  • npm organization:
  • Documentation: (소개, 패키지, 시작하기, 모범 사례, ADRs)
0 조회
Back to Blog

관련 글

더 보기 »

맞춤형 댓글 섹션 만들기

React 앱에 댓글 섹션 추가 – 부피 없이 “시중에 나와 있는 모든 솔루션은 당신에게 자체 UI를 강요하거나, 원하지 않는 방대한 CSS를 쏟아붓거나, …”

Vue Composition API: Computed와 Ref 프로퍼티 설명

안녕하세요, 사랑스러운 독자 여러분. Vue 3와 TypeScript를 사용하고 있다면 `ref`와 `computed`를 여러 번 보았을 것입니다. 이들은 튜토리얼은 물론 실제 프로젝트에서도 자주 등장합니다.

성능 비교: React vs WebForms Core

네트워크 요청, 대역폭 소비 및 클라이언트 실행 모델에 집중하세요. 현대 웹 아키텍처에서 성능은 렌더링 속도만을 의미하지 않습니다. A criti...