C4 Component 다이어그램: 예제와 함께 보는 완벽 가이드
컴포넌트 다이어그램은 C4 모델의 레벨 3이며 — 가장 평판이 나쁜 레벨입니다. 레벨 1(System Context)은 그리기 쉽고 좀처럼 바뀌지 않습니다. 레벨 2(Container)는 배포하는 것에 깔끔하게 대응됩니다. 그런데 레벨 3은? 단일 컨테이너의 내부로 확대하는데, 이는 개발자가 패키지를 재구성할 때마다 바뀐다는 뜻입니다. 대부분의 팀은 아예 건너뛰거나 한 번 그리고 썩게 내버려 둡니다.
이것은 안타까운 일입니다. 잘 유지된 컴포넌트 다이어그램은 코드베이스에 합류하는 개발자에게 가장 유용한 단일 산출물이기 때문입니다. 그것은 모든 신입이 묻는 질문에 답합니다: "X에 대한 로직이 실제로 어디에 사는가?"
이 가이드는 C4 컴포넌트 다이어그램이 무엇인지, UML 컴포넌트 다이어그램과 어떻게 다른지, 언제 레벨 3이 유지보수 비용을 치를 가치가 있는지(그리고 없는지), 완전하게 작성한 예제, 컴포넌트 다이어그램을 무용지물로 만드는 실수들, 그리고 모든 것을 손으로 하지 않고도 그것들을 정확하게 유지하는 방법을 다룹니다.
C4 모델 자체가 처음이라면, 먼저 C4 모델 완벽 가이드부터 읽고 여기로 돌아오세요.
C4 Component 다이어그램이란 무엇인가?
컴포넌트 다이어그램은 하나의 컨테이너 — 컨테이너 다이어그램의 배포 가능한 단위 하나 — 를 열어 그 안의 컴포넌트를 드러냅니다.
C4 용어로 컴포넌트는 잘 정의된 인터페이스 뒤에 자리한, 관련된 기능의 응집된 묶음입니다. 애플리케이션 내부의 주요 빌딩 블록을 생각해 보세요:
- HTTP 컨트롤러 또는 핸들러 그룹
- 비즈니스 로직의 일부를 소유하는 도메인 서비스
- 리포지토리 또는 데이터 접근 계층
- 외부 API를 감싸는 클라이언트
- 미들웨어, 인터셉터, 또는 백그라운드 워커
핵심 단어는 묶음입니다. 컴포넌트는 코드에 대한 추상화이지, 단일 클래스나 파일이 아닙니다. OrderService 컴포넌트는 열두 개의 파일에 걸쳐 있을 수 있지만, 개념적으로는 하나입니다: 주문 비즈니스 로직을 담당하는 컨테이너의 일부. 용어집 정의에서 설명하듯이, C4 컴포넌트는 "단일 책임을 가진 코드의 상위 수준 묶음"이지 — 프로그래밍 언어 클래스에 대한 1:1 매핑이 아닙니다.
컴포넌트 다이어그램이 답하는 것
- 이 컨테이너는 내부적으로 어떻게 구조화되어 있는가?
- 어떤 컴포넌트가 어떤 책임을 소유하는가?
- 컴포넌트들이 요청을 처리하기 위해 어떻게 협력하는가?
- 데이터베이스와 외부 시스템으로의 호출은 어디서 비롯되는가?
의도적으로 빼는 것
- 개별 클래스, 인터페이스, 함수(그것은 레벨 4, 코드 다이어그램입니다)
- 다른 컨테이너의 내부
- 배포 및 인프라 세부 사항
다이어그램당 하나의 컨테이너, 컴포넌트만. 클래스를 그리고 있는 자신을 발견한다면, 너무 멀리 확대한 것입니다.
C4 Component 다이어그램 vs. UML Component 다이어그램
이것이 사람들을 끊임없이 헷갈리게 합니다. UML에도 "컴포넌트 다이어그램"이라고 불리는 것이 있는데 — 같은 것이 아니기 때문입니다.
UML 컴포넌트 다이어그램은 소프트웨어 컴포넌트를 제공 인터페이스와 요구 인터페이스를 가진 단위로 모델링하며(유명한 막대사탕-소켓 표기법), 종종 물리적 패키징, 아티팩트, 배포 관계를 강조합니다. 형식적인 표기 규칙과 정밀한 메타모델을 갖추고 있습니다.
C4 컴포넌트 다이어그램은 더 느슨하고 더 실용적입니다. 그것은 단순히 줌 계층 구조의 레벨 3입니다: 컴포넌트를 위한 상자, 관계를 위한 화살표, 각각에 짧은 텍스트 설명. 배워야 할 특별한 표기법은 없습니다. 그 가치는 표기법 자체가 아니라 계층 구조 — 모든 컴포넌트 상자는 특정 컨테이너 안에 살고, 그것은 특정 시스템 안에 삽니다 — 에서 나옵니다.
실무에서: 누군가 C4 맥락에서 "컴포넌트 다이어그램"을 요청한다면, 그들은 신입 개발자가 2분 안에 읽을 수 있는 하나의 컨테이너 내부에 대한 구조적 지도를 원하는 것입니다. 막대사탕 인터페이스와 <<artifact>> 스테레오타입을 원한다면, 그들은 UML을 요청하는 것입니다.
언제 레벨 3을 유지할 가치가 있는가?
대부분의 가이드가 건너뛰는 정직한 답이 여기 있습니다: 레벨 3은 전체 C4 모델에서 노력 대비 안정성 비율이 가장 나쁜 레벨입니다.
컨텍스트 다이어그램은 1년에 몇 번 바뀝니다. 컨테이너 다이어그램은 서비스를 추가하거나 제거할 때 바뀝니다 — 아마 월 단위로. 컴포넌트 다이어그램은 누군가 패키지를 리팩터링하거나, 서비스를 추출하거나, 모듈 이름을 바꿀 때마다 바뀝니다. 손으로 유지한다면, 끊임없는 정원 가꾸기에 등록하는 셈이며, 멈추는 순간 다이어그램은 거짓말을 시작합니다.
그러니 그 노력을 어디에 쓸지 신중하게 결정하세요.
컴포넌트 다이어그램을 만들 때:
- 컨테이너가 정말로 복잡할 때. 15개의 패키지, 여러 계층, 명확하지 않은 경계를 가진 백엔드 API는 지도를 받을 자격이 있습니다. 엔드포인트 세 개짜리 CRUD 서비스는 그렇지 않습니다.
- 구조가 의도적인 설계를 구현할 때. 헥사고날 아키텍처, CQRS, 또는 깔끔한 계층화 체계를 사용한다면, 컴포넌트 다이어그램은 의도된 구조를 명시적으로 만들어 줍니다 — 그리고 풀 리퀘스트가 그것을 위반할 때 가리킬 무언가를 줍니다.
- 여러 팀이 같은 컨테이너를 건드릴 때. 공유 코드에는 공유된 멘탈 모델이 필요합니다.
- 온보딩이 병목일 때. 신입 개발자가 컨테이너를 익히는 데 몇 주가 걸린다면, 컴포넌트 다이어그램은 첫 채용으로 본전을 뽑습니다.
건너뛸 때:
- 컨테이너가 작고 그 폴더 구조가 자명할 때.
- 컨테이너가 서드파티일 때(Redis의 내부를 그리지는 않습니다).
- 아무도 그것을 최신으로 유지하는 데 전념하지 않을 때. 노후화된 컴포넌트 다이어그램은 없는 것보다 나쁩니다 — 그것은 자신 있게 개발자를 더 이상 존재하지 않는 코드로 보냅니다.
이것이 바로 레벨 3이 대부분의 팀이 건너뛰거나 자동화하는 레벨인 이유입니다. 실제 코드 구조로부터 컴포넌트를 생성하고 — 그것과 대조하여 검증하는 것 — 은 손으로 그린 다이어그램을 죽이는 유지보수 세금을 제거합니다. 이에 대해서는 아래에서 더 다룹니다.
작성된 예제: API 컨테이너 내부
이것을 구체적으로 만들어 봅시다. C4 모델 가이드의 전자상거래 플랫폼을 가져와 단일 컨테이너로 확대해 봅시다: Order API (Go). 레벨 2에서 그것은 하나의 상자입니다. 레벨 3에서 그것은 컴포넌트로 열립니다.
컴포넌트
| 컴포넌트 | 책임 |
|---|---|
| Auth Middleware | 들어오는 요청에서 JWT 토큰을 검증하고, 요청 컨텍스트에 사용자 신원을 주입함 |
| Order Controller | 주문 생성, 조회, 취소를 위한 REST 엔드포인트; 요청 검증과 응답 직렬화 |
| Admin Controller | 백오피스 주문 관리(환불, 수동 상태 변경)를 위한 REST 엔드포인트 |
| Order Service | 핵심 비즈니스 로직: 주문 생명주기, 가격 책정 규칙, 재고 확인, 결제 오케스트레이션 |
| Order Repository | 데이터 접근 계층; SQL을 통해 주문을 영속화하고 쿼리함 |
| Payment Client | Stripe API를 감쌈; 승인, 캡처, 환불을 처리함 |
| Email Adapter | SendGrid를 통해 트랜잭션 이메일(주문 확인, 배송 업데이트)을 보냄 |
| Event Publisher | 도메인 이벤트(OrderPlaced, OrderCancelled)를 Kafka에 발행함 |
관계
[Auth Middleware] --> [Order Controller] : Passes authenticated requests
[Auth Middleware] --> [Admin Controller] : Passes authenticated requests (admin role)
[Order Controller] --> [Order Service] : Delegates business operations
[Admin Controller] --> [Order Service] : Delegates back-office operations
[Order Service] --> [Order Repository] : Reads/writes orders
[Order Service] --> [Payment Client] : Authorizes and captures payments
[Order Service] --> [Email Adapter] : Triggers transactional emails
[Order Service] --> [Event Publisher] : Emits domain events
[Order Repository] --> [Order Database (PostgreSQL)] : SQL
[Payment Client] --> [Payment Gateway (Stripe)] : HTTPS/REST
[Email Adapter] --> [Email Service (SendGrid)] : HTTPS/REST
[Event Publisher] --> [Message Queue (Kafka)] : Publishes events
데이터베이스, Stripe, SendGrid, Kafka가 가장자리에 나타나는 것에 주목하세요. 그것들은 이 컨테이너의 컴포넌트가 아닙니다 — 그것들은 이웃하는 컨테이너이자 외부 시스템입니다 — 하지만 외부로 나가는 호출이 어디서 비롯되는지 보여주는 것이 바로 다이어그램을 유용하게 만드는 것입니다.
이 다이어그램이 신입 개발자에게 알려주는 것
30초 안에, 이 팀에 합류하는 개발자는 다음을 배웁니다:
- 요청 경로: 미들웨어 → 컨트롤러 → 서비스 → 리포지토리. 비즈니스 로직이 사는 곳은 정확히 한 군데이며, 그것은 컨트롤러가 아닙니다.
- 경계: 모든 외부 호출은 전용 어댑터(
Payment Client,Email Adapter)를 거칩니다. Stripe와 통신해야 한다면, 클라이언트를 확장합니다. 컨트롤러에 SDK를 임포트하지 않습니다. - 부수 효과: 주문은 Kafka에 이벤트를, SendGrid를 통해 이메일을 생성합니다. 이메일이 전송되지 않으면, 어떤 두 컴포넌트를 확인해야 하는지 압니다.
- 코드를 어디에 추가할지: 새로운 "기프트 카드" 기능은 명백히 컨트롤러, 서비스, 그리고 어쩌면 새로운 클라이언트의 변경이 필요합니다 — 그리고 다이어그램은 따라야 할 패턴을 보여줍니다.
마지막 요점은 과소평가되어 있습니다. 컴포넌트 다이어그램은 구조를 설명할 뿐만 아니라 — 그것을 처방합니다. 그것은 기여자에게 "이 코드베이스와 일관된" 것이 어떤 모습인지 알려줍니다.
컴포넌트 다이어그램의 흔한 실수
하나의 클래스를 하나의 컴포넌트로 매핑하기
가장 빈번한 실수입니다. 컨테이너에 80개의 클래스가 있고 컴포넌트 다이어그램에 80개의 상자가 있다면, 추가 단계를 거친 클래스 다이어그램을 그린 것입니다. 컴포넌트는 묶음입니다: OrderController(하나의 컴포넌트)는 다섯 개의 핸들러 클래스를 포괄할 수 있습니다. 컨테이너당 5-15개의 컴포넌트를 목표로 하세요. 20개를 넘어선다면, 추상화가 너무 세분화되어 있거나 — 컨테이너가 너무 많은 일을 하고 있는 것입니다.
모든 컨테이너를 레벨 3에서 문서화하기
대칭성은 유혹적입니다: "우리에게는 12개의 컨테이너가 있으니, 12개의 컴포넌트 다이어그램이 필요해." 저항하세요. 그 다이어그램 대부분은 결코 읽히지도, 업데이트되지도 않을 것입니다. 복잡성이 실제로 아프게 하는 두세 개의 컨테이너를 문서화하고, 나머지는 폴더 구조가 말하게 두세요.
다이어그램을 썩게 내버려 두기
레벨 3은 다른 어떤 레벨보다 빠르게 표류합니다. 1월에 그린 컴포넌트 다이어그램은 6월에는 아마 존재하지 않을 컨테이너를 설명합니다. 모든 리팩터, 모든 추출된 패키지, 모든 이름 바뀐 모듈이 그 간극을 넓힙니다. 그리고 자신 있게 틀린 다이어그램은 다이어그램이 없는 것보다 나쁩니다: 그것은 개발자를 두 분기 전에 삭제된 컴포넌트를 찾아 헤매게 만듭니다. 유지보수를 자동화할 수 없다면, 최소한 그 컨테이너의 풀 리퀘스트 체크리스트에 "컴포넌트 다이어그램 업데이트"를 넣으세요.
책임 없이 컴포넌트 그리기
설명 없이 OrderManager라고 레이블이 붙은 상자는 노이즈입니다. 모든 컴포넌트는 한 줄짜리 책임 진술("JWT 토큰을 검증하고 사용자 신원을 주입함")을 지녀야 합니다. 그 문장을 쓸 수 없다면, 컴포넌트 경계가 아마 잘못된 것입니다.
구조 대신 구현 세부 사항 보여주기
제네릭, 디자인 패턴, 헬퍼 유틸리티 — 그중 어느 것도 레벨 3에 속하지 않습니다. 컴포넌트의 흥미로운 부분이 그것이 어떻게 구현되었는지라면, 그것은 코드 다이어그램(또는 더 흔하게는 코드 자체)의 일입니다.
Archyl이 컴포넌트 다이어그램을 정확하게 유지하는 방법
위의 모든 것이 같은 결론을 가리킵니다: 컴포넌트 다이어그램은 가치가 있지만, 손으로 유지하는 것은 지는 게임입니다. 이것이 바로 Archyl이 해결하기 위해 만들어진 문제입니다.
AI 디스커버리가 코드로부터 컴포넌트를 추출합니다
컴포넌트를 손으로 그리는 대신, 리포지토리를 연결하고 AI 디스커버리를 실행합니다. Archyl은 코드 구조 — 패키지, 모듈, 계층, 명명 규칙 — 를 분석하고 C4 모델을 제안합니다. 여기에는 각 컨테이너 내부의 컴포넌트와 그것들 사이의 관계가 포함됩니다. handlers/, service/, repository/ 패키지를 가진 Go 서비스는 위 예제에서 보여준 것과 정확히 같은 종류의 컴포넌트 다이어그램으로 돌아옵니다. 제안을 검토하여 수락하거나 조정하면, 몇 분 안에 레벨 3 모델을 갖게 됩니다.
표류 탐지가 발산을 표시합니다
이것이 레벨 3을 살아있게 유지하는 부분입니다. Archyl은 컴포넌트를 리포지토리의 실제 파일 및 디렉터리에 연결하기 때문에, 문서화된 컴포넌트가 코드에 여전히 존재하는지 지속적으로 확인할 수 있습니다. 누군가 패키지를 삭제하거나, 모듈 이름을 바꾸거나, 계층을 재구성하면, 표류 점수가 떨어지고 영향받은 컴포넌트가 표시됩니다. 컴포넌트 다이어그램은 스냅샷이기를 멈추고 모니터링되는 계약이 됩니다.
Architecture as Code
디스커버리보다 명시적인 정의를 선호한다면, Archyl은 C4 모델 — 시스템, 컨테이너, 컴포넌트, 관계 — 을 리포지토리에 사는 YAML로 정의하는 것을 지원합니다. 컴포넌트 다이어그램은 버전 관리되고, 풀 리퀘스트에서 검토되며, 자동으로 렌더링됩니다. 표류 탐지와 결합하면, 코드의 유지보수 특성을 가진 레벨 3 문서를 얻게 됩니다.
FAQ
C4 컴포넌트 다이어그램과 UML 컴포넌트 다이어그램의 차이는 무엇인가요?
UML 컴포넌트 다이어그램은 제공/요구 인터페이스, 아티팩트, 스테레오타입을 가진 형식적인 표기법으로, 컴포넌트를 패키징된 단위로 모델링하는 데 초점을 맞춥니다. C4 컴포넌트 다이어그램은 C4 줌 계층 구조의 레벨 3입니다: 하나의 특정 컨테이너 내부 컴포넌트에 대한 실용적인 상자-화살표 뷰. C4에는 형식적인 표기 요구사항이 없습니다 — 그 가치는 표기가 아니라 일관된 계층 구조(시스템 → 컨테이너 → 컴포넌트 → 코드)에서 나옵니다.
컴포넌트는 클래스와 같은가요?
아니요. C4 컴포넌트는 잘 정의된 인터페이스 뒤에 있는 코드의 응집된 묶음입니다 — 그것은 하나의 클래스, 열두 개의 클래스, 패키지, 또는 모듈로 구현될 수 있습니다. 컴포넌트 다이어그램에 클래스당 하나의 상자가 있다면, 한 줌 레벨 너무 깊이 들어간 것입니다.
모든 컨테이너에 컴포넌트 다이어그램이 필요한가요?
아니요. 그리고 모든 컨테이너를 레벨 3에서 문서화하려는 것은 C4를 포기하는 가장 빠른 방법 중 하나입니다. 복잡하거나, 여러 팀에 걸쳐 공유되거나, 온보딩에 핵심적인 컨테이너에 대해서만 컴포넌트 다이어그램을 만드세요. 나머지에 대해서는 컨테이너 다이어그램에 읽기 쉬운 폴더 구조를 더한 것으로 충분합니다.
컴포넌트 다이어그램은 몇 개의 컴포넌트를 보여줘야 하나요?
대략 5개에서 15개. 5개보다 적으면 다이어그램은 아마 컨테이너 다이어그램이 말하지 않은 것을 아무것도 말해주지 않을 것입니다. 20개보다 많으면 컴포넌트 경계가 너무 세분화되어 있거나 컨테이너 자체를 분할해야 합니다.
정확하게 유지되는 컴포넌트 다이어그램을 원하시나요? Archyl을 무료로 사용해 보고 몇 분 안에 코드베이스로부터 C4 모델 — 컴포넌트 포함 — 을 생성하세요. 또는 계속 읽어보세요: C4 모델이란 무엇인가? 완벽 가이드 | C4 컨테이너 다이어그램 가이드 | C4 코드 다이어그램 가이드 | 용어집의 컴포넌트 다이어그램.