이 글은 Claude Opus 4.5 을 이용해 초안이 작성되었으며, 이후 퇴고를 거쳤습니다.


Subgraph 기본#

Subgraph는 관련된 노드들을 논리적으로 그룹화하는 기능입니다. 시스템의 계층 구조나 도메인 영역을 시각적으로 구분할 때 유용합니다.

기본 문법#

flowchart TB
    subgraph 그룹명
        A --> B
    end
    C --> A

ID와 제목 분리#

Subgraph에 별도의 ID를 지정하면 참조가 쉬워집니다.

flowchart TB
    subgraph api[API Layer]
        A[Controller]
        B[Service]
    end
    subgraph db[Data Layer]
        C[(MySQL)]
        D[(Redis)]
    end
    A --> B
    B --> C
    B --> D

Subgraph 방향 제어#

이것이 Mermaid 레이아웃의 핵심입니다. direction 키워드로 각 subgraph 내부의 배치 방향을 개별적으로 지정할 수 있습니다.

direction 키워드#

flowchart LR
    subgraph TOP[상단 영역]
        direction TB
        A --> B --> C
    end
    subgraph BOTTOM[하단 영역]
        direction TB
        D --> E --> F
    end
    TOP --> BOTTOM

주의사항#

중요: Subgraph 내부의 노드가 외부 노드와 직접 연결되면, 해당 subgraph의 direction 설정이 무시되고 부모 flowchart의 방향을 따릅니다.

flowchart LR
    subgraph sub1[Direction이 무시되는 경우]
        direction TB
        A --> B
    end
    B --> C
    %% B가 외부 노드 C와 연결되어 direction TB가 무시됨

레이아웃 패턴 마스터하기#

패턴 1: 수평으로 나란한 그룹들 (메인 LR)#

전체는 좌→우로 배치하고, 각 그룹 내부는 위→아래로 배치합니다.

flowchart LR
    subgraph Frontend[프론트엔드]
        direction TB
        F1[React App]
        F2[Redux Store]
        F3[API Client]
        F1 --> F2 --> F3
    end

    subgraph Backend[백엔드]
        direction TB
        B1[API Gateway]
        B2[Auth Service]
        B3[Core Service]
        B1 --> B2
        B1 --> B3
    end

    subgraph Database[데이터베이스]
        direction TB
        D1[(PostgreSQL)]
        D2[(Redis Cache)]
        D1 --- D2
    end

    Frontend --> Backend --> Database

패턴 2: 수직으로 쌓인 그룹들 (메인 TB)#

전체는 위→아래로 배치하고, 각 그룹 내부는 좌→우로 배치합니다.

flowchart TB
    subgraph Presentation[프레젠테이션 계층]
        direction LR
        P1[Web UI] --- P2[Mobile App] --- P3[Admin Panel]
    end

    subgraph Business[비즈니스 계층]
        direction LR
        B1[User Service] --- B2[Order Service] --- B3[Payment Service]
    end

    subgraph Data[데이터 계층]
        direction LR
        D1[(Users DB)] --- D2[(Orders DB)] --- D3[(Payment DB)]
    end

    Presentation --> Business --> Data

패턴 3: 3열 그리드 레이아웃#

flowchart TB
    subgraph Row1[입력 처리]
        direction LR
        A1[HTTP 요청] --- A2[검증] --- A3[파싱]
    end

    subgraph Row2[비즈니스 로직]
        direction LR
        B1[인증] --- B2[권한확인] --- B3[처리]
    end

    subgraph Row3[출력 처리]
        direction LR
        C1[직렬화] --- C2[압축] --- C3[응답]
    end

    Row1 --> Row2 --> Row3

패턴 4: 중첩 Subgraph#

Subgraph는 중첩이 가능합니다.

flowchart TB
    subgraph Cloud[AWS Cloud]
        subgraph VPC[VPC]
            subgraph Public[Public Subnet]
                ALB[Application Load Balancer]
            end
            subgraph Private[Private Subnet]
                EC2[EC2 Instances]
                RDS[(RDS)]
            end
        end
    end

    User[사용자] --> ALB
    ALB --> EC2
    EC2 --> RDS

패턴 5: 마이크로서비스 아키텍처#

flowchart LR
    Client[Client App]

    subgraph Gateway[API Gateway]
        direction TB
        Kong[Kong]
        Auth[Auth Middleware]
        Kong --> Auth
    end

    subgraph Services[Microservices]
        direction TB
        subgraph Core[Core Domain]
            direction LR
            UserSvc[User Service]
            OrderSvc[Order Service]
        end
        subgraph Support[Support Domain]
            direction LR
            NotifySvc[Notification]
            LogSvc[Logging]
        end
    end

    subgraph Data[Data Stores]
        direction TB
        MySQL[(MySQL)]
        Redis[(Redis)]
        Kafka[Kafka]
    end

    Client --> Gateway --> Services
    Core --> Data
    Support --> Kafka

Subgraph 간 연결#

Subgraph 자체를 노드처럼 연결할 수 있습니다.

flowchart LR
    subgraph A[서비스 A]
        A1 --> A2
    end
    subgraph B[서비스 B]
        B1 --> B2
    end
    subgraph C[서비스 C]
        C1 --> C2
    end

    A --> B
    B --> C
    A --> C

내부 노드와 외부를 연결할 수도 있습니다.

flowchart LR
    subgraph Producer[Producer]
        P[메시지 생성]
    end

    Queue[(Message Queue)]

    subgraph Consumer[Consumer]
        C[메시지 처리]
    end

    P --> Queue --> C

스타일링#

classDef로 스타일 정의#

flowchart LR
    classDef primary fill:#4F46E5,stroke:#3730A3,color:white
    classDef secondary fill:#10B981,stroke:#059669,color:white
    classDef danger fill:#EF4444,stroke:#DC2626,color:white
    classDef database fill:#F59E0B,stroke:#D97706,color:black

    A[시작]:::primary --> B[처리]:::secondary
    B --> C{조건}
    C -->|성공| D[(저장)]:::database
    C -->|실패| E[에러]:::danger

여러 노드에 스타일 적용#

flowchart LR
    classDef serviceStyle fill:#E0E7FF,stroke:#4F46E5

    A[Service A]
    B[Service B]
    C[Service C]

    class A,B,C serviceStyle

    A --> B --> C

연결선 스타일링#

flowchart LR
    A --> B --> C --> D

    linkStyle 0 stroke:#ff3,stroke-width:4px
    linkStyle 1 stroke:#3f3,stroke-width:2px
    linkStyle 2 stroke:#33f,stroke-width:2px,stroke-dasharray:5

linkStyle 뒤의 숫자는 0부터 시작하는 연결선의 순서입니다.

default 클래스#

default라는 이름의 클래스는 모든 노드에 자동 적용됩니다.

flowchart LR
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px

    A --> B --> C

실전 예제: 주문 처리 시스템#

flowchart TB
    classDef userAction fill:#DBEAFE,stroke:#3B82F6
    classDef process fill:#D1FAE5,stroke:#10B981
    classDef decision fill:#FEF3C7,stroke:#F59E0B
    classDef data fill:#E0E7FF,stroke:#6366F1
    classDef error fill:#FEE2E2,stroke:#EF4444

    subgraph Client[클라이언트]
        direction LR
        Order[주문 요청]:::userAction
    end

    subgraph OrderService[주문 서비스]
        direction TB
        Validate[주문 검증]:::process
        CheckStock{재고 확인}:::decision
        Reserve[재고 예약]:::process
        NoStock[재고 부족]:::error
    end

    subgraph PaymentService[결제 서비스]
        direction TB
        Payment[결제 처리]:::process
        PayResult{결제 결과}:::decision
        PayFail[결제 실패]:::error
    end

    subgraph FulfillmentService[배송 서비스]
        direction TB
        Ship[배송 준비]:::process
        Notify[알림 발송]:::process
    end

    subgraph DataStores[데이터 저장소]
        direction LR
        OrderDB[(주문 DB)]:::data
        InventoryDB[(재고 DB)]:::data
        EventBus[Event Bus]:::data
    end

    Order --> Validate
    Validate --> CheckStock
    CheckStock -->|있음| Reserve
    CheckStock -->|없음| NoStock
    Reserve --> Payment
    Payment --> PayResult
    PayResult -->|성공| Ship
    PayResult -->|실패| PayFail
    Ship --> Notify

    Reserve --> InventoryDB
    Payment --> OrderDB
    Notify --> EventBus

보이지 않는 연결선으로 레이아웃 조정#

때로는 노드 배치를 원하는 대로 조정하기 위해 보이지 않는 연결선이 필요합니다.

flowchart LR
    A --> B
    B --> C

    %% D를 C와 같은 높이에 배치하고 싶을 때
    A ~~~ D
    D --> E

~~~는 보이지 않는 연결선을 만듭니다. 렌더링 엔진에게 노드 간의 관계를 암시하여 배치를 조정합니다.

Configuration으로 전역 설정#

YAML frontmatter로 다이어그램 전체 설정을 변경할 수 있습니다.

---
config:
  flowchart:
    curve: basis
    defaultRenderer: elk
---
flowchart LR
    A --> B --> C

주요 설정 옵션#

옵션 설명 기본값
curve 연결선 곡선 스타일 basis
defaultRenderer 렌더러 (dagre, elk) dagre
nodeSpacing 노드 간 간격 50
rankSpacing 계층 간 간격 50

ELK 렌더러#

복잡한 다이어그램에서는 elk 렌더러가 더 나은 레이아웃을 제공하기도 합니다.

---
config:
  flowchart:
    defaultRenderer: elk
---
flowchart TB
    subgraph A[Group A]
        A1 --> A2 --> A3
    end
    subgraph B[Group B]
        B1 --> B2 --> B3
    end
    A1 --> B1
    A2 --> B2
    A3 --> B3

레이아웃 제어 요약 치트시트#

원하는 결과 메인 방향 Subgraph 내부 방향
그룹들이 가로로 나란히, 내부는 세로 LR direction TB
그룹들이 세로로 쌓임, 내부는 가로 TB direction LR
모두 가로로 LR direction LR
모두 세로로 TB direction TB

배치 원칙#

  1. 외부 연결 주의: Subgraph 내부 노드가 외부와 연결되면 direction이 무시됨
  2. Subgraph 단위 연결 권장: 복잡한 레이아웃에서는 subgraph 자체를 연결
  3. 보이지 않는 연결선 활용: ~~~로 배치 힌트 제공
  4. ELK 렌더러 시도: 기본 렌더러로 원하는 결과가 안 나오면 elk 사용