Нотация C4: полный гайд по моделированию архитектуры с примерами, разбором ошибок и промптом для ИИ

Схемы архитектуры часто сводятся к совокупности «квадратиков и стрелочек», которые каждый участник команды интерпретирует по-своему. C4 помогает решить эту проблему и предоставляет возможность последовательно представить систему на различных уровнях.
В 2023 году я опубликовала на Хабре статью «Нотация моделирования архитектуры С4 — примеры диаграмм и инструменты». К моменту ее публикации она уже набрала более 280 тысяч просмотров.
С того времени я накопила большой объем новых примеров, уточнений и выявила множество типичных ошибок, которые встречаются у новичков. Поэтому я выпускаю обновленный и расширенный гайд с кучей картинок, который сделает работу с C4 максимально понятной и удобной.

Это полное практическое руководство я создала для русскоязычных IT-команд и сообщества GetAnalyst. В спорных ситуациях вы сможете обратиться к статье и быстро найти ответ, а мне не придётся снова и снова разбирать одни и те же вопросы в личных сообщениях и чатах :)
В нём я разбираю все уровни C4, их элементы и правила, реальные примеры архитектуры, распространенные ошибки и инструменты. Статья будет полезна системным аналитикам, архитекторам, разработчикам, тестировщикам и другим IT-специалистам, которые работают с архитектурой систем и для которых важно ее понимать.
Теория для знакомства с C4
Нотация моделирования архитектуры C4 была создана британским разработчиком и программным архитектором Саймоном Брауном. Первая публикация с названием C4 вышла в 2011 году, что делает эту нотацию относительно новой.
Она была создана из-за реальной проблемы: отсутствие нормальных нотаций моделирования, которые помогают разложить архитектуру для команды. Это мешало Саймону Брауну в процессе чтения лекций его студентам, поэтому он решил свою проблему созданием своей нотации.
Созданная им нотация C4 позволяет рассматривать архитектуру последовательно. Мы начинаем с общего представления системы, а затем приближаем отдельные части и изучаем их более детально.
Название C4 происходит как раз из-за четырех уровней детализации:
Context (Контекст) - система, ее пользователи и окружающая среда.
Container (Контейнер) - приложения и хранилища внутри системы.
Component (Компонент) - компоненты внутри выбранного контейнера.
Code (Код) - реализация отдельного компонента на уровне кода.
Каждый последующий уровень раскрывает элементы предыдущего. Однако, создание всех четырех диаграмм не обязательно. Достаточно выбрать те уровни, которые действительно необходимы вашей команде.
Все элементы нотации C4
В C4 используется небольшой набор элементов. На каждом следующем уровне к ним добавляются новые детали.
В разных инструментах набор и внешний вид элементов могут немного отличаться. Поэтому я подготовила для вас шпаргалки с ключевыми элементами из инструментов, которыми сама постоянно пользуюсь для построения C4-диаграмм.
Draw.io - визуальный редактор
Чтобы начать работать с C4 в draw.io, убедитесь, что у вас включены соответствующие фигуры в настройках.

Level 1:

Level 2:
Ссылка на документацию от автора нотации Саймона Брауна, которая поясняет, как правильно использовать элемент "контейнер-труба", предназначенный для брокеров или очередей/топиков: https://c4model.com/abstractions/queues-and-topics

Level 3:

Level 4:
Я не буду детально разбирать элементы уровня C4/Code в этой статье. Этот уровень описывает уже не общую архитектуру системы, а структуру программного кода внутри конкретного компонента: классы, интерфейсы, функции, объекты, таблицы баз данных и их связи.
Чаще всего для этого используется UML-диаграмма классов, но это также может быть ER-диаграмма или другая подходящая визуализация. То есть у C4/Code нет отдельного универсального набора фигур: способ отображения зависит от языка программирования, структуры приложения и выбранного инструмента.
Такие диаграммы обычно создаются уже после начала разработки и могут автоматически генерироваться средствами IDE или UML-инструментов.
Кроме того, код меняется достаточно часто, поэтому нарисованная вручную схема быстро устаревает. Автор C4 также считает этот уровень необязательным и рекомендует использовать его только для наиболее важных или сложных компонентов. Поэтому здесь я просто покажу два примера C4/Code с официального сайта, чтобы было понятно, как может выглядеть этот уровень детализации.

https://c4model.com/diagrams/code
Structurizr - диаграмма C4 через код
https://playground.structurizr.com/
Все подробные описания элементов и их назначение я оставила на картинках выше — к элементам draw.io. Здесь нюансы и детали по элементам уже не дублирую.
При работе со Structurizr важно разделять тип элемента и его визуальное оформление.
В коде уже предусмотрены основные элементы C4:
Person,Software System,ContainerиComponent.Дополнительные обозначения — например,
External,Database,MessageBrokerили Gateway — мы создаём с помощью тегов.
Сам по себе тег не меняет внешний вид элемента. Для него необходимо задать стиль: цвет, форму, границу и другие параметры. Например, база данных, брокер и API Gateway на уровне C4 остаются контейнерами, но визуально могут отображаться как цилиндр, труба или шестиугольник.
В draw.io форма выбирается вручную, а в Structurizr задаётся через связку tags и styles.
По умолчанию набор форм в C4 минимален: та же база данных, брокер или Backend-приложение могут выглядеть как обычные прямоугольники. Поэтому дальше для каждого элемента я покажу не только код его создания, но и теги со стилями, которые помогут сделать диаграмму более наглядной и единообразной.
C4/Context
Элемент | Как использовать | Код Structurizr |
Пользователь (Person) | Пользователь или группа пользователей, которые взаимодействуют с моделируемой системой. Это может быть покупатель, администратор, оператор или курьер. | Маска: Пример: |
Внешний пользователь (Person с tag) | На схеме можно выделить неавторизованного пользователя, сотрудника внешней организации, пользователя внешней системы. В C4 это не отдельный тип элемента, а обычный | Маска: Пример: |
Основная система (Software System) | Система, для которой строится контекстная диаграмма. Здесь показывается вся система целиком, а не отдельный Frontend, Backend или микросервис. | Маска: Пример: |
Внешняя система | Система за пределами моделируемой системы, с которой выполняется интеграция. Это может быть платёжный сервис, служба доставки или сервис уведомлений. | Маска: Пример: |
Обычная связь | Показывает взаимодействие между пользователем и системой или между двумя системами. Название связи лучше формулировать как действие. | Маска: Пример: |
Связь с указанием протокола или технологии | Показывает не только действие, но и способ интеграции. Автор C4 предлагает не перегружать Context техническими деталями, но в GetAnalyst мы рекомендуем указывать их, если это делает схему понятнее. | Маска: Пример: |
Представление и название диаграммы для System Context | Определяет, для какой системы строится контекстная диаграмма, какие элементы в неё входят и как они располагаются. | Пример: |
Все стили и теги из последней колонки в итоговом коде объединяются в один блок:
views {
systemContext shop "SystemContext" {
include *
autoLayout lr
title "C4 / Context — Интернет-магазин"
description "Система для продажи товаров онлайн."
}
styles {
element "Person" {
shape Person
background #08427b
color #ffffff
}
element "Software System" {
shape RoundedBox
background #1168bd
color #ffffff
}
element "External" {
background #8c8596
color #ffffff
}
relationship "Relationship" {
color #707070
thickness 2
routing Orthogonal
}
}
}C4/Container
Элемент | Как использовать | Код Structurizr |
Граница системы (System Boundary) | Граница показывает, какие приложения и хранилища относятся к интернет-магазину, а какие системы находятся за его пределами. | Пример: |
Frontend-приложение | Web-приложение или Desktop-приложение, которое запускается на устройстве пользователя. Обычный виджет или UI-модуль внутри приложения отдельным контейнером не является. | Пример: Стиль: |
Мобильное приложение. | Аналог Frontend. | Пример: Стиль: |
Backend-приложение | Монолитное Backend-приложение, сервис, микросервис, независимые сервис-Worker или другое самостоятельно запускаемое приложение. Классы, модули и библиотеки внутри него относятся уже к уровню Component. | Пример: Базовый стиль контейнера: |
API Gateway / BFF | Единая точка входа в систему, которая выполняет маршрутизацию, проксирование и общую обработку запросов. Шестиугольник — визуальное правило, рекомендуемое GetAnalyst. Можно использовать обычный прямоугольник. | Пример: Стиль: |
База данных или файловое хранилище | Реляционная или NoSQL-база данных, объектное либо файловое хранилище. Если система использует несколько независимых хранилищ, каждое показывается отдельным контейнером. | Пример БД: Пример ФХ:
Стили:
Можно добавить цвета, чтобы различать что есть ФХ, а что - БД. Будет далее в примерах диаграмм. |
Брокер, очередь или топик | Можно показать Kafka или RabbitMQ целиком, если очереди и топики неважны для этой схемы. Если необходимо раскрыть каналы обмена, лучше показать отдельные очереди и топики — именно этот вариант рекомендует автор C4. | Пример 1 — брокер целиком: Пример 2 — отдельный топик: Стили:
|
Название Container-диаграммы | Создаёт Container-диаграмму интернет-магазина и показывает его Frontend, Backend, базы данных, брокер и связанные внешние системы. |
|
C4/Component
Элемент | Как использовать | Код Structurizr |
Граница контейнера (Container Boundary) | Граница объединяет все части кода, которые относятся к сервису заказов. Сам сервис является контейнером, а контроллеры, сервисы и репозитории внутри него — компонентами. | Пример: Граница не создаётся отдельной командой. Structurizr автоматически показывает её вокруг компонентов, вложенных в контейнер. |
Компонент (Component) | Компонентом может быть контроллер, сервис с бизнес-логикой, репозиторий, модуль авторизации, клиент внешней системы или обработчик событий из брокера. Это модуль кода. Компонент работает внутри контейнера и не разворачивается отдельно. | Пример:
Первое значение — идентификатор компонента в коде. Далее указываются его название, ответственность и технология реализации. Стиль: |
Название Component-диаграммы | Создаёт диаграмму внутреннего устройства сервиса заказов: контроллер, бизнес-сервис, репозиторий, интеграционные клиенты и обработчики событий. | Пример:
|
Пример полной структуры в model:
model {
shop = softwareSystem "Интернет-магазин" {
orderService = container "Сервис заказов" "Управляет заказами" "Java, Spring Boot" {
ordersController = component "Контроллер заказов" "Принимает и проверяет API-запросы" "Spring REST Controller"
orderManagement = component "Сервис управления заказами" "Выполняет бизнес-логику работы с заказами" "Spring Service"
ordersRepository = component "Репозиторий заказов" "Работает с данными заказов" "Spring Data Repository"
paymentClient = component "Клиент платёжной системы" "Вызывает API платёжного сервиса" "REST Client"
eventsHandler = component "Обработчик событий заказов" "Обрабатывает сообщения из брокера" "Kafka Consumer"
}
}
}Общие правила оформления
У каждого элемента должны быть понятные название, тип и краткое описание.
Для контейнеров и компонентов указывают технологии реализации.
Каждая стрелка показывает однонаправленную связь. На ней нужно указать назначение взаимодействия, а для связей между контейнерами — протокол или технологию.
Как создать C4 с нуля
Если вы только осваиваете C4-модель, рекомендую начать с нашего обучающего видео-подкаста на YouTube. В нем я пошагово разбираю уровни модели и на примерах демонстрирую, как строить архитектурные диаграммы.
В этой статье я покажу примеры C4-диаграмм для двух проектов из этого видео:
платформу аренды недвижимости,
систему интернет-магазина.
Я покажу готовые схемы, созданные в draw.io в ходе обучающего подкаста, и затем их код для Structurizr DSL. Этот код можно будет использовать в качестве шаблона для своих проектов и передавать нейросетям (ИИ) как пример, чтобы они помогали строить и обновлять архитектурные диаграммы.
Нотация C4 за 90 минут: как проектировать архитектуру на примере реальной задачи
https://t.me/getanalysts/3364
C4 / Context
Цель: наглядно видеть пользователей и интеграции системы.
Контекстная диаграмма представляет систему с точки зрения ее окружения, то есть что именно мы разрабатываем, кто будет пользоваться нашей системой и с какими внешними системами наша система будет взаимодействовать.
На этом уровне система рассматривается как единое целое — без Frontend, Backend, микросервисов, баз данных и других внутренних деталей.
На схеме показываются:
моделируемая система;
пользователи и их роли;
внешние системы;
основные связи между ними.
Пример C4 / Context для Интернет-магазина (draw.io):

Код C4 / Context для Интернет-магазина:
Код C4 / Context для Интернет-магазина
workspace "Интернет-магазин — C4 / Context" "Контекстная диаграмма интернет-магазина" {
!identifiers hierarchical
!impliedRelationships false
model {
registeredCustomer = person "Покупатель" "Авторизованный пользователь. Покупает товары в интернет-магазине."
guestCustomer = person "Гость" "Неавторизованный пользователь. Просматривает каталог и покупает товары." {
tags "External"
}
administrator = person "Администратор" "Управляет системой, работает с отчётами, регистрирует поставки и контролирует остатки товаров."
supportAgent = person "Сотрудник техподдержки" "Помогает пользователям при возникновении сложностей в работе с системой."
shop = softwareSystem "Интернет-магазин" "Система для продажи товаров онлайн."
unisender = softwareSystem "Unisender" "Сервис отправки email- и SMS-сообщений." {
tags "External"
}
firebase = softwareSystem "Firebase" "Сервис отправки push-уведомлений." {
tags "External"
}
raifPay = softwareSystem "RaifPay" "Интернет-эквайринг для приёма онлайн-платежей." {
tags "External"
}
cdek = softwareSystem "СДЭК" "Система доставки товаров покупателям и формирования данных для складской обработки отправлений." {
tags "External"
}
registeredCustomer -> shop "Использует"
guestCustomer -> shop "Использует"
administrator -> shop "Использует"
supportAgent -> shop "Использует"
shop -> unisender "Вызывает API для отправки email и SMS" "JSON/HTTPS (REST API)"
shop -> firebase "Вызывает API для отправки push-уведомлений" "JSON/HTTPS (REST API)"
shop -> raifPay "Вызывает API для проведения платежей" "JSON/HTTPS (REST API)"
shop -> cdek "Вызывает API для оформления доставки" "JSON/HTTPS (REST API)"
}
views {
systemContext shop "SystemContext" "C4 / Context — Интернет-магазин" {
include *
autoLayout lr 300 200
title "C4 / Context — Интернет-магазин"
}
theme default
styles {
element "Person" {
shape Person
background #08427b
color #ffffff
stroke #06345f
fontSize 22
}
element "Software System" {
shape RoundedBox
background #1168bd
color #ffffff
stroke #0b4f91
fontSize 22
}
element "External" {
background #8c8596
color #ffffff
stroke #6c6577
border solid
}
relationship "Relationship" {
color #707070
thickness 2
routing Orthogonal
jump true
fontSize 18
}
}
}
}
Вопросы и ответы по C4 / Context
>> Что делать, если внутри одной компании есть две системы, за которые отвечают разные подразделения и которые фактически являются отдельными продуктами экосистемы?
В начале необходимо выяснить, какая система находится в центре внимания данной диаграммы. На классической диаграмме C4 / Context отображается одна система. В нашей цветовой палитре она обозначена темно-синим прямоугольником.
Если же речь идет о второй системе, то даже если она относится к той же фирме, то в рамках выбранного контекста она будет представлена как внешняя (серая). Затем для этой второй системы будут созданы отдельные диаграммы Context и Container. При этом на ее собственной контекстной диаграмме она станет главной и будет показана синим, а первая система — внешней.
Если же необходимо продемонстрировать несколько равных систем в рамках одной экосистемы, то следует использовать System Landscape Diagram от C4 — карту систем организации без акцента на одной из них. Официально областью System Context является одна программная система, а System Landscape предназначена исключительно для нескольких систем организации или подразделения.
>> Каких пользователей показывать серыми?
В нашей легенде синим цветом обозначены пользователи, которые имеют дело с приложениями нашей системы, которые моделируются. Пользователи могут быть не только сотрудниками организации, но и её клиентами, а также сотрудниками других организаций. Главное, что они применяют наше web-, mobile- или другое клиентское приложение.
Пользователь, который взаимодействует с интерфейсами внешних систем, но не взаимодействует с нашими приложениями, может быть обозначен серым цветом. Неавторизованные пользователи могут быть также обозначены серым цветом, если это поможет визуально отделить их от авторизованных пользователей.
В то же время, цвет — это дополнительное правило, а не обязательное требование C4. Его значение должно быть объяснено в легенде диаграммы.
>> Типичная ошибка новичка: внешняя система показывается фигурой пользователя.
Внешнюю систему нельзя обозначать фигурой пользователя. Пользователь всегда остаётся Person, а система — Software System, независимо от выбранного цвета.
Дополнительный пример C4 / Context для Платформы Аренды Недвижимости (draw.io):

C4 / Container
Цель: показать карту приложений системы и их взаимодействия как внутренние, так и внешние.
Диаграмма C4 / Container детализирует систему с предыдущего уровня и демонстрирует внутреннюю архитектуру системы: какие приложения и хранилища входят в систему, за что они отвечают, какие технологии используют и как взаимодействуют между собой.
Важно не путать C4-контейнер с Docker-контейнером. В C4 контейнер — это самостоятельная среда выполнения приложения или хранения данных. Приложение-контейнер, как правило, можно отдельно запустить и развернуть.
Отдельный репозиторий, команда или релизный цикл — хорошие дополнительные признаки контейнера, но не обязательные. Например, два приложения могут храниться в одном монорепозитории, но запускаться как отдельные процессы — тогда это два контейнера. И наоборот: библиотека может находиться в отдельном репозитории, но выполняться внутри Backend-приложения — тогда это не контейнер.
Если просто: отдельно запускаемое и исполняемое приложение = отдельный контейнер.
На Container-диаграмме могут быть показаны:
веб-приложение;
монолитный Backend;
клиентское веб-приложение: Single Page Application или PWA;
мобильное приложение;
Desktop-приложение;
отдельный сервис или микросервис;
API Gateway;
Worker или фоновый обработчик, если это самостоятельно работающее приложение;
отдельно запускаемый консольный скрипт;
БД;
файловое или объектное хранилище;
кэш;
брокер или очередь / топик брокера сообщений.
Пример C4 / Container для Интернет-магазина (draw.io):


Код C4 / Container для Интернет-магазина с микросервисной архитектурой:
Код C4 / Container для Интернет-магазина с микросервисной архитектурой
workspace "Интернет-магазин — C4 / Container" "Контейнерная диаграмма микросервисной архитектуры интернет-магазина" {
!identifiers hierarchical
!impliedRelationships false
model {
registeredCustomer = person "Покупатель" "Авторизованный пользователь. Покупает товары в интернет-магазине."
guestCustomer = person "Гость" "Неавторизованный пользователь. Просматривает каталог и покупает товары." {
tags "External"
}
administrator = person "Администратор" "Управляет системой, работает с отчётами, регистрирует поставки и контролирует остатки товаров."
supportAgent = person "Сотрудник техподдержки" "Помогает пользователям при возникновении сложностей в работе с системой."
shop = softwareSystem "Интернет-магазин" "Система для продажи товаров онлайн." {
iosApp = container "iOS Покупателя" "Авторизация, просмотр каталога, работа с корзиной и оформление заказов." "Swift" {
tags "MobileApp"
}
androidApp = container "Android Покупателя" "Авторизация, просмотр каталога, работа с корзиной и оформление заказов." "Kotlin" {
tags "MobileApp"
}
webApp = container "Web-Покупателя" "Авторизация, просмотр каталога, работа с корзиной и оформление заказов." "JavaScript" {
tags "WebApp"
}
adminApp = container "Админка" "Работа с отчётами, товарами, поставками, пользователями и обращениями." "JavaScript" {
tags "WebApp"
}
apiGateway = container "API Gateway" "Единая точка входа. Проверяет и маршрутизирует запросы к внутренним сервисам." "Kong" {
tags "Gateway"
}
authService = container "Сервис аутентификации и авторизации" "Аутентифицирует пользователей, проверяет права доступа и управляет токенами." "Java, Spring Boot"
authDb = container "БД аутентификации" "Хранит учётные данные и параметры аутентификации пользователей." "PostgreSQL" {
tags "Database"
}
paymentService = container "Сервис платежей" "Создаёт платежи, обрабатывает их статусы и возвраты." "Java, Spring Boot"
paymentDb = container "БД платежей" "Хранит платежи, статусы операций и данные возвратов." "PostgreSQL" {
tags "Database"
}
catalogService = container "Сервис каталога товаров" "Управляет товарами, категориями, ценами и остатками." "Java, Spring Boot"
catalogDb = container "БД каталога товаров" "Хранит карточки товаров, категории, цены и остатки." "PostgreSQL" {
tags "Database"
}
searchService = container "Сервис поиска товаров" "Выполняет полнотекстовый поиск и фильтрацию товаров." "Java, Spring Boot"
searchIndex = container "Поисковый индекс товаров" "Хранит поисковый индекс каталога товаров." "Elasticsearch" {
tags "Database"
}
cartService = container "Сервис корзины" "Управляет составом и состоянием корзины покупателя." "Java, Spring Boot"
cartDb = container "БД корзины" "Хранит корзины покупателей и добавленные товары." "PostgreSQL" {
tags "Database"
}
deliveryService = container "Сервис доставки" "Оформляет доставку и отслеживает статусы отправлений." "Java, Spring Boot"
deliveryDb = container "БД доставки" "Хранит данные отправлений и историю изменения их статусов." "PostgreSQL" {
tags "Database"
}
loyaltyService = container "Сервис лояльности" "Управляет скидками, бонусами и персональными предложениями." "Java, Spring Boot"
loyaltyDb = container "БД лояльности" "Хранит бонусные счета, скидки и историю начислений." "PostgreSQL" {
tags "Database"
}
supportService = container "Сервис техподдержки" "Управляет обращениями и чатом покупателей с техподдержкой." "Java, Spring Boot"
supportDb = container "БД чата и поддержки" "Хранит обращения, сообщения и статусы обработки." "PostgreSQL" {
tags "Database"
}
supportFiles = container "Файловое хранилище чата" "Хранит файлы, прикреплённые к обращениям и сообщениям." "Amazon S3" {
tags "FileStorage"
}
userService = container "Сервис управления пользователями" "Управляет профилями, контактными данными и настройками пользователей." "Java, Spring Boot"
userDb = container "БД пользователей" "Хранит профили и настройки пользователей." "PostgreSQL" {
tags "Database"
}
userFiles = container "Файловое хранилище пользователей" "Хранит аватары и документы пользователей." "Amazon S3" {
tags "FileStorage"
}
notificationService = container "Сервис уведомлений" "Формирует и отправляет email-, SMS- и push-уведомления." "Java, Spring Boot"
notificationDb = container "БД уведомлений" "Хранит шаблоны, историю и статусы отправки уведомлений." "PostgreSQL" {
tags "Database"
}
broker = container "Брокер" "Обеспечивает асинхронный обмен событиями между сервисами." "Apache Kafka" {
tags "MessageBroker"
}
}
unisender = softwareSystem "Unisender" "Сервис отправки email- и SMS-сообщений." {
tags "External"
}
firebase = softwareSystem "Firebase" "Сервис отправки push-уведомлений." {
tags "External"
}
raifPay = softwareSystem "RaifPay" "Интернет-эквайринг для приёма онлайн-платежей." {
tags "External"
}
cdek = softwareSystem "СДЭК" "Система оформления и отслеживания доставки товаров покупателям." {
tags "External"
}
registeredCustomer -> shop.iosApp "Использует"
registeredCustomer -> shop.androidApp "Использует"
registeredCustomer -> shop.webApp "Использует"
guestCustomer -> shop.webApp "Использует"
administrator -> shop.adminApp "Использует"
supportAgent -> shop.adminApp "Использует"
shop.iosApp -> shop.apiGateway "Вызывает API" "JSON/HTTPS (REST API)"
shop.androidApp -> shop.apiGateway "Вызывает API" "JSON/HTTPS (REST API)"
shop.webApp -> shop.apiGateway "Вызывает API" "JSON/HTTPS (REST API)"
shop.adminApp -> shop.apiGateway "Вызывает API" "JSON/HTTPS (REST API)"
shop.iosApp -> raifPay "Отображает платёжную форму" "HTTPS"
shop.androidApp -> raifPay "Отображает платёжную форму" "HTTPS"
shop.webApp -> raifPay "Отображает платёжную форму" "HTTPS"
shop.apiGateway -> shop.authService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.paymentService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.catalogService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.searchService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.cartService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.deliveryService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.loyaltyService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.supportService "Вызывает API" "JSON/HTTPS (REST API)"
shop.apiGateway -> shop.userService "Вызывает API" "JSON/HTTPS (REST API)"
shop.authService -> shop.authDb "Читает и пишет данные" "SQL/TCP"
shop.paymentService -> shop.paymentDb "Читает и пишет данные" "SQL/TCP"
shop.catalogService -> shop.catalogDb "Читает и пишет данные" "SQL/TCP"
shop.searchService -> shop.searchIndex "Читает и пишет данные" "JSON/HTTPS"
shop.cartService -> shop.cartDb "Читает и пишет данные" "SQL/TCP"
shop.deliveryService -> shop.deliveryDb "Читает и пишет данные" "SQL/TCP"
shop.loyaltyService -> shop.loyaltyDb "Читает и пишет данные" "SQL/TCP"
shop.supportService -> shop.supportDb "Читает и пишет данные" "SQL/TCP"
shop.supportService -> shop.supportFiles "Читает и пишет файлы" "HTTPS"
shop.userService -> shop.userDb "Читает и пишет данные" "SQL/TCP"
shop.userService -> shop.userFiles "Читает и пишет файлы" "HTTPS"
shop.notificationService -> shop.notificationDb "Читает и пишет данные" "SQL/TCP"
shop.cartService -> shop.catalogService "Получает данные о товарах и ценах" "JSON/HTTPS (REST API)"
shop.paymentService -> raifPay "Создаёт платежи и возвраты" "JSON/HTTPS (REST API)"
raifPay -> shop.paymentService "Передаёт статусы платежей" "Webhook/JSON/HTTPS"
shop.deliveryService -> cdek "Создаёт отправления" "JSON/HTTPS (REST API)"
cdek -> shop.deliveryService "Передаёт статусы доставки" "Webhook/JSON/HTTPS"
shop.notificationService -> unisender "Отправляет email и SMS" "JSON/HTTPS (REST API)"
shop.notificationService -> firebase "Отправляет push-уведомления" "Firebase Admin SDK/HTTPS"
shop.paymentService -> shop.broker "Публикует события платежей" "Kafka Protocol"
shop.catalogService -> shop.broker "Публикует события каталога" "Kafka Protocol"
shop.deliveryService -> shop.broker "Публикует события доставки" "Kafka Protocol"
shop.loyaltyService -> shop.broker "Публикует события лояльности" "Kafka Protocol"
shop.userService -> shop.broker "Публикует события пользователей" "Kafka Protocol"
shop.searchService -> shop.broker "Читает события каталога" "Kafka Protocol"
shop.notificationService -> shop.broker "Читает события для отправки уведомлений" "Kafka Protocol"
}
views {
container shop "Containers" "C4 / Container — Интернет-магазин — микросервисы" {
include *
autoLayout lr 400 180
title "C4 / Container — Интернет-магазин — микросервисы"
}
theme default
styles {
element "Person" {
shape Person
background #08427b
color #ffffff
stroke #06345f
fontSize 20
}
element "Software System" {
shape RoundedBox
background #1168bd
color #ffffff
stroke #0b4f91
fontSize 20
}
element "External" {
background #8c8596
color #ffffff
stroke #6c6577
border solid
}
element "Container" {
shape RoundedBox
background #28a4d9
color #ffffff
stroke #1f8fbd
fontSize 19
}
element "WebApp" {
shape WebBrowser
width 500
height 300
}
element "MobileApp" {
shape MobileDevicePortrait
width 320
height 500
}
element "Gateway" {
shape Hexagon
width 420
height 340
}
element "Database" {
shape Cylinder
width 460
height 280
}
element "FileStorage" {
shape Cylinder
width 460
height 280
}
element "MessageBroker" {
background #FFC0CB
color #000000
shape Pipe
width 500
height 300
}
relationship "Relationship" {
color #707070
thickness 2
routing Orthogonal
jump true
fontSize 16
width 300
}
}
}
}
Вопросы и ответы по C4 / Container
>> Worker — контейнер или компонент?
Если Worker работает как самостоятельное приложение или процесс, отдельно запускается, разворачивается и масштабируется, то его следует изображать как отдельный контейнер.
Если же обработчик сообщений работает внутри основного Backend-приложения и разворачивается вместе с ним, то это не отдельный контейнер, а компонент этого Backend-приложения.
Аналогичное правило применимо к Consumer, Scheduler и Batch-задачам: важно не то, какую они выполняют функцию, а наличие у них собственной runtime-границы.
>> Что не является контейнером?
Контейнерами обычно не являются:
классы, пакеты и модули кода;
библиотеки, JAR, DLL и другие сборки;
контроллеры, сервисы и репозитории внутри приложения;
обычные виджеты и UI-компоненты;
копии и реплики одного приложения;
серверы, виртуальные машины, Kubernetes Pods и Nodes.
Последние относятся уже к физическому развёртыванию системы и показываются на Deployment-диаграмме. Docker-контейнер также не обязательно соответствует C4-контейнеру: это разные уровни абстракции.
При этом отдельную схему БД можно показать как отдельный контейнер, если это помогает в понимании архитектуры.
>> Монолит и микросервисы (выше оба примера)
Container-диаграммы монолитной и микросервисной системы будут заметно различаться.
В монолитной архитектуре Backend обычно показывается одним контейнером. Его внутренние контроллеры, сервисы, репозитории и модули затем можно раскрыть на уровне C4 / Component.
В микросервисной архитектуре каждый независимо работающий сервис представлен отдельным контейнером. На этом же уровне отображаются его базы данных, очереди, топики, Gateway, Worker-приложения и другие важные компоненты архитектуры.
>> Можно ли показать весь сервисный / микросервисный Backend одним прямоугольником, а далее детализировать его на диаграмме компонентов? Т.е. компоненты будут сервисами и микросервисами
По нотации — нет, нельзя.
Если очень хочется и вы готовы добавить пояснения к картинке — можно.
Компоненты — это части кода внутри одного приложения. Микросервисы — самостоятельно работающие приложения, поэтому они должны быть показаны только на уровне Container.
Если микросервисов слишком много, лучше создать несколько сфокусированных Container-диаграмм, чем переносить их на уровень Component. Формы и цвета элементов можно выбирать самостоятельно.
Дополнительный пример C4 / Container для Платформы Аренды Недвижимости (draw.io):

C4 / Component
Диаграмма C4 / Component раскрывает внутреннее устройство одного контейнера и показывает основные части его кода: за что они отвечают, с какими компонентами взаимодействуют и какие технологии используются для их реализации.
Компонент — это логическая группа связанной функциональности, модуль кода. Он работает внутри своего контейнера, в том же процессе, и не запускается, не масштабируется и не разворачивается самостоятельно.
Компонентами могут быть:
контроллер или группа контроллеров, принимающих API-запросы;
сервис с бизнес-логикой;
модуль авторизации внутри сервиса;
репозиторий или другой слой доступа к данным;
клиент или адаптер для работы с внешней системой;
обработчик сообщений из очереди или топика;
внутренний планировщик задач;
модуль формирования уведомлений;
функциональный модуль Frontend-приложения;
API-клиент, хранилище состояния или модуль авторизации на Frontend.
Не нужно показывать каждый класс, метод, кнопку, виджет или вспомогательную функцию. На этом уровне оставляют только те части кода, которые важны для понимания архитектуры контейнера.
Типичная ошибка — сначала показать весь Backend как один контейнер, а затем раскрыть самостоятельно разворачиваемые микросервисы как его компоненты. Это смешение уровней: микросервисы должны быть показаны на Container-диаграмме.
Уровень Component необязателен. Его стоит использовать для сложных или важных приложений, когда Container-диаграммы уже недостаточно для понимания внутренней архитектуры. Поскольку структура кода меняется чаще, такие схемы необходимо регулярно обновлять или по возможности генерировать автоматически.
Пример C4 / Container для Сервиса Уведомлений в системе Интернет-магазина:

Пример кода Structurizr для C4 / Container Сервиса Уведомлений в системе Интернет-магазина
workspace "Интернет-магазин — C4 / Component" "Компонентная диаграмма сервиса уведомлений" {
!identifiers hierarchical
!impliedRelationships false
model {
shop = softwareSystem "Интернет-магазин" "Система для продажи товаров онлайн." {
apiGateway = container "API Gateway" "Единая точка входа и маршрутизации запросов." "Kong" {
tags "Gateway"
}
broker = container "Брокер" "Передаёт события между сервисами интернет-магазина." "Apache Kafka" {
tags "MessageBroker"
}
notificationService = container "Сервис уведомлений" "Формирует и отправляет email-, SMS- и push-уведомления." "Java, Spring Boot" {
apiController = component "API уведомлений" "Принимает команды на отправку уведомлений и запросы истории." "Spring REST Controller" {
tags "Controller"
}
eventHandler = component "Обработчик событий" "Получает события из Kafka и передаёт их в бизнес-логику уведомлений." "Spring Kafka Listener" {
tags "EventHandler"
}
notificationManager = component "Управление уведомлениями" "Определяет канал доставки и управляет процессом отправки уведомления." "Spring Service" {
tags "BusinessLogic"
}
templateRenderer = component "Формирование сообщений" "Выбирает шаблон и подставляет данные получателя и события." "Spring Service" {
tags "BusinessLogic"
}
notificationRepository = component "Репозиторий уведомлений" "Сохраняет историю и статусы отправки уведомлений." "Spring Data JPA" {
tags "Repository"
}
unisenderClient = component "Клиент Unisender" "Отправляет email и SMS через API Unisender." "REST Client" {
tags "Integration"
}
firebaseClient = component "Клиент Firebase" "Отправляет push-уведомления через Firebase." "Firebase Admin SDK" {
tags "Integration"
}
}
notificationDb = container "БД уведомлений" "Хранит шаблоны, историю и статусы отправки уведомлений." "PostgreSQL" {
tags "Database"
}
}
unisender = softwareSystem "Unisender" "Сервис отправки email- и SMS-сообщений." {
tags "External"
}
firebase = softwareSystem "Firebase" "Сервис отправки push-уведомлений." {
tags "External"
}
shop.apiGateway -> shop.notificationService.apiController "Вызывает API" "JSON/HTTPS (REST API)"
shop.notificationService.apiController -> shop.notificationService.notificationManager "Передаёт команду на отправку"
shop.notificationService.eventHandler -> shop.broker "Читает события" "Kafka Protocol"
shop.notificationService.eventHandler -> shop.notificationService.notificationManager "Передаёт данные события"
shop.notificationService.notificationManager -> shop.notificationService.templateRenderer "Формирует сообщение"
shop.notificationService.notificationManager -> shop.notificationService.notificationRepository "Сохраняет статус отправки"
shop.notificationService.notificationManager -> shop.notificationService.unisenderClient "Отправляет email или SMS"
shop.notificationService.notificationManager -> shop.notificationService.firebaseClient "Отправляет push-уведомление"
shop.notificationService.notificationRepository -> shop.notificationDb "Читает и пишет данные" "SQL/TCP"
shop.notificationService.unisenderClient -> unisender "Вызывает API" "JSON/HTTPS (REST API)"
shop.notificationService.firebaseClient -> firebase "Отправляет push-уведомление" "Firebase Admin SDK/HTTPS"
}
views {
component shop.notificationService "Components" "C4 / Component — Сервис уведомлений" {
include *
autoLayout lr 350 180
title "C4 / Component — Интернет-магазин — Сервис уведомлений"
}
theme default
styles {
element "Software System" {
shape RoundedBox
background #1168bd
color #ffffff
stroke #0b4f91
fontSize 20
}
element "External" {
background #8c8596
color #ffffff
stroke #6c6577
border solid
}
element "Container" {
shape RoundedBox
background #28a4d9
color #ffffff
stroke #1f8fbd
fontSize 19
}
element "Gateway" {
shape Hexagon
width 420
height 340
}
element "Database" {
shape Cylinder
width 460
height 280
}
element "MessageBroker" {
shape Pipe
width 500
height 300
}
element "Component" {
shape Component
background #5cb9e1
color #ffffff
stroke #1f8fbd
width 470
height 260
fontSize 19
}
element "Controller" {
background #28a4d9
}
element "EventHandler" {
background #74bcde
color #10384a
}
element "BusinessLogic" {
background #4bb0dc
}
element "Repository" {
background #1f9dd6
}
element "Integration" {
background #3aa9d8
}
relationship "Relationship" {
color #707070
thickness 2
routing Orthogonal
jump true
fontSize 17
width 280
}
}
}
}C4 / Code
Не разбираю этот уровень, о чем писала при обзоре элементов нотации.
Это могут быть ER-диаграммы БД или диаграммы классов UML.
Полезные ссылки:
Инструменты для создания диаграмм C4
Полный обзор инструментов я делала в статье «Нотация моделирования архитектуры С4 — примеры диаграмм и инструменты».
Здесь оставляю список с моими реальными впечатлениями и опытом:
Draw.io — мой основной выбор. Бесплатный, удобный и отлично подходит для ручной отрисовки C4. Использую постоянно.
Miro — не рекомендую: без специальных шаблонов нет нормального набора элементов C4, а работать с ними в итоге не очень удобно.
Microsoft Visio — не использую. При наличии Draw.io не вижу причин начинать.
Structurizr — использую постоянно, особенно сейчас, когда код диаграмм удобно генерировать с помощью ИИ. Позволяет хранить все уровни C4 в одной модели, увеличивать схемы и отслеживать связи. На больших диаграммах визуал и автоматическое расположение элементов иногда неудобны.
PlantUML — позволяет строить C4 через код, в том числе с помощью ИИ, но визуально мне не нравится, поэтому не использую.
MermaidChart — позволяет строить C4 через код. Он удобен, но из-за лимитов по тарифу и привычки работы в Structurizr почти не трогаю его.
Как создать C4-диаграмму с помощью нейросетей (ИИ)
Используйте любую нейросеть, которая вам нравится. Главное — хороший промпт и/или настроенный с ним AI-скилл.
Для визуализации кода: https://playground.structurizr.com/
Работай как опытный системный архитектор с опытом проектирования enterprise-решений и систем уровня Big Tech. Ты на экспертном уровне владеешь моделью C4 Саймона Брауна и создал сотни архитектурных диаграмм с помощью Structurizr DSL.
Основной источник истины — официальный сайт модели C4: https://c4model.com. Для правил оформления и практических рекомендаций используй статью Екатерины Ананьевой: <сюда вставьте ссылку на статью>. Если между источниками возникнет противоречие, приоритет имеет официальный сайт C4.
Твоя задача:
Создать диаграмму системы <название системы> на уровне C4 / <название уровня> и предоставить полный код Structurizr DSL.
Описание системы:
<Включите голосовой ввод и расскажите ИИ, что именно хотите показать на диаграмме.
Не знаете, с чего начать? Укажите хотя бы:
+ список приложений и хранилищ системы;
+ пользователей и их роли;
+ внешние системы;
+ основные взаимодействия;
+ тип Backend: монолит, сервисы, микросервисы или другой вариант.
Даже при подробном описании воспринимайте полученный результат как черновик архитектуры, который необходимо проверить.>
Если информации недостаточно или возможны разные архитектурные решения, сначала задай уточняющие вопросы. Не придумывай отсутствующие требования самостоятельно.
Пример кода Structurizr для C4 / <название уровня>:
<Сюда вставьте подходящий пример кода Structurizr из этой статьи>
Перед выдачей результата проверь корректность синтаксиса и убедись, что код запускается в Structurizr: https://playground.structurizr.com/.
Сначала предоставь полный готовый код одним блоком, а после него кратко перечисли принятые допущения и решения, которые необходимо дополнительно проверить.А ещё в одном файле Structurizr можно организовать сразу все три уровня C4.
Но хотя бы что-то в этой статье я всё-таки не расскажу — оставлю это вам для самостоятельного изучения 😉
Подборка примеров и проектов
Можно изучать и использовать как ориентир для своих проектов. В подборке есть и монолиты, и микросервисные системы с брокерами.
🔗 RideFlow — заказ такси
🔗 TelMed — телемедицина
🔗 BookingGA — сервис аренды недвижимости
🔗 GreenChargeGA — зарядки для электроавто
🔗 CityGA — поиск мероприятий в городе
🔗 AdFlowGA — рекламный сервис
🔗 Пример архитектуры C4 в Miro
Все эти ссылки и дополнительные материалы по C4 можно найти в посте TG или посте VK.
Также у меня в базе знаний есть задача с собеседования с максимально подробным разбором ошибок, которые допускают в C4:

Заключение
Надеюсь, этот гайд оказался для вас действительно полезным: я попыталась подробно разобрать все уровни C4, привести практические примеры и указать на типичные ошибки.
Если я что-то упустила или у вас остались вопросы, пишите в комментариях — постараюсь на всё ответить.
А в качестве благодарности за эту большую работу буду искренне рада, если вы подпишетесь на GetAnalyst — моё сообщество для системных и бизнес-аналитиков — в Telegram, ВК или MAX.
Спасибо за внимание — и понятных вам архитектурных схем! 💙
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.