O que é o Diagrama do Modelo C4?
O Diagrama do Modelo C4é um framework arquitetônico hierárquico de quatro níveis projetado para documentar arquiteturas de software com diferentes graus de detalhe granular. Criado por Simon Brown, o C4 evita caixas e linhas vagas estruturando mapas de sistemas em quatro lentes de abstração explícitas: Contexto (alcance de nível de sistema), Container (Aplicações e armazenamentos de dados), Componente (módulos internos), e Código (implementações de nível de classe).
Para implementar este modelo de forma eficaz em texto, engenheiros usam a extensão oficial C4-PlantUMLbiblioteca padrão de extensão. Esta biblioteca substitui formas brutas de UML por macros especializadas que injetam automaticamente cores distintas, formas e campos de metadados para usuários, sistemas e bancos de dados. Com VPasCode, você pode definir esses ambientes aninhados de forma limpa no código. O motor de layout roteia dinamicamente vetores de conexão e dimensiona campos de texto sem comprometer a geometria do seu layout.
Guia de Sintaxe Principal: Elementos e Construções
Construir um modelo C4 válido usando PlantUML depende da importação dos arquivos de biblioteca corretos, da seleção de macros estruturais, da definição de limites e do uso de links de relacionamento especializados.
1. Importação dos Arquivos da Biblioteca Padrão C4
O C4-PlantUMLa extensão é dividida em arquivos individuais que mapeiam diretamente para os níveis distintos do modelo de abstração. Para evitar lentidões de desempenho ou erros do compilador, você deve importar apenas a camada de arquivo específica que seu diagrama almeja:
@startuml
' Inclua o arquivo de camada C4 específico necessário
!include <C4/C4_Context>
' Use C4_Container ou C4_Component para mapas arquitetônicos mais profundos
2. Declarando Atores e Sistemas Principais (Nível de Contexto)
No nível de contexto do sistema, você modela componentes internos, dependências externas e usuários humanos. A biblioteca padrão fornece macros específicas que aceitam um ID, uma etiqueta visual e uma tag descritiva opcional:
Pessoa(id, "Rótulo", "Descrição")— Representa um perfil de usuário humano ou ator do sistema.Sistema(id, "Rótulo", "Descrição")— Representa uma aplicação de software interna principal ou ecossistema de serviços.System_Ext(id, "Rótulo", "Descrição")— Representa um sistema externo ou dependência de API de terceiros (aparece com uma paleta de cores cinza explícita).
@startuml C4_Elements
!include <C4/C4_Context>
Person(customer, "Cliente Bancário", "Um cliente com uma conta bancária pessoal")
System(banking_sys, "Sistema Bancário Central", "Gerencia transações financeiras")
System_Ext(mail_sys, "Serviço de E-mail", "Portal de notificação SMTP interno") 
3. Limites Explodidos (Níveis de Container e Componente)
Ao aprofundar-se na camada de Container, você modela aplicativos web, microserviços e bancos de dados. Você pode isolar esses elementos internos dentro de uma caixa lógica explícita usando oSystem_Boundary()envoltório de macro:
!include <C4/C4_Container>
System_Boundary(c1, "Ecossistema de Comércio Eletrônico") {
Container(web_app, "Aplicativo de Página Única", "React & TypeScript", "Fornece recursos do usuário por meio de visualização web")
ContainerDb(database, "Banco de Dados Relacional", "PostgreSQL", "Armazena perfis de usuário e históricos de lançamentos")
} 
4. Mapeamento de Relacionamentos Técnicos
Em vez de depender de linhas tracejadas básicas, o C4 utiliza um formato de macros de comunicação explícito comoRel(De_ID, Para_ID, "Rótulo", "Tecnologia"). Isso mantém seus mapas de arquitetura altamente legíveis, exigindo que cada conexão indique seu propósito e o protocolo de transporte subjacente (como HTTPS, gRPC ou AMQP):
!include <C4/C4_Container>
Person(customer, "Cliente Bancário", "Um cliente com uma conta bancária pessoal")
System(banking_sys, "Sistema Bancário Central", "Gerencia transações financeiras")
System_Ext(mail_sys, "Serviço de E-mail", "Portal de notificação SMTP interno")
System_Boundary(c1, "Ecossistema de Comércio Eletrônico") {
Container(web_app, "Aplicativo de Página Única", "React & TypeScript", "Fornece recursos do usuário por meio de visualização web")
ContainerDb(database, "Banco de Dados Relacional", "PostgreSQL", "Armazena perfis de usuário e históricos de lançamentos")
}
Rel(customer, web_app, "Utiliza recursos da loja por meio de", "HTTPS")
Rel(web_app, database, "Lê e escreve dados transacionais por meio de", "SQL/TCP") 
Melhores Práticas para Arquiteturas C4 Legíveis
- Nunca misture níveis de abstração:Mantenha seus diagramas focados em uma única camada. Não misture componentes internos de granularidade fina em um mapa de contexto de sistema de alto nível. Se um sistema ficar muito complexo, divida-o em um diagrama separado e dedicado ao nível de Container.
- Defina explicitamente as tecnologias:Sempre utilize o quarto parâmetro em seus
Rel()macros para indicar a tecnologia ou protocolo exato sendo usado (por exemplo,"JSON/HTTPS"ou"JDBC"). Isso fornece ao seu time o contexto essencial de implementação de um só olhar. - Aproveite as substituições de layout direcional: Se seus componentes começarem a se empilhar de forma desconfortável, use macros de relacionamento direcional (como
Rel_D()para baixo,Rel_R()para direita, ouRel_L()para esquerda) para corrigir manualmente o fluxo arquitetônico.
Exemplos Reais de PlantUML C4
Exemplo 1: Layout de Contexto de Sistema de Alto Nível (Nível 1)
Este plano funcional modela um diagrama padrão de Contexto de Sistema de Nível 1, detalhando como um cliente interage com um aplicativo de banco online e suas dependências externas.
@startuml
!include <C4/C4_Context>
title Diagrama de Contexto do Sistema para o Sistema de Banco Online
Pessoa(cliente, "Cliente de Banco Pessoal", "Um cliente do banco com contas pessoais.")
Sistema(sistema_bancario, "Sistema de Banco Online", "Permite que os clientes visualizem informações financeiras e realizem transferências.")
Sistema_Ext(sistema_email, "Subsistema de E-mail", "O cluster interno de servidores corporativos de e-mail SendGrid da empresa.")
Rel(cliente, sistema_bancario, "Utiliza o painel online via")
Rel_R(sistema_bancario, sistema_email, "Envia alertas e códigos de verificação usando", "SMTP")
@enduml 
Análise da Sintaxe: Este diagrama foca exclusivamente no escopo de alto nível. A System_Ext macro aplica automaticamente um perfil de cor cinza ao serviço de e-mail, separando visualmente o sistema principal das dependências externas. A Rel_R macro força o motor de layout a posicionar o nó de e-mail diretamente à direita do bloco do sistema bancário.
Exemplo 2: Topologia de Container de Microserviço com Profundidade (Nível 2)
Este plano avançado de empresa desdobra um sistema em seus aplicativos containerizados constituintes e armazenamentos de dados isolados, mostrando como o tráfego da web passa por um gateway de API até os microserviços de backend.
@startuml
!include <C4/C4_Container>
title Diagrama de Container para Gateway do Portal de Pagamentos
Pessoa(mercadante, "Parceiro Mercantil Web", "Integra pontos finais de checkout da plataforma em seus sites.")
Sistema_Fronteira(portal_escopo, "Ecossistema do Gateway de Pagamentos") {
Container(gateway_api, "Proxy de Roteamento de API", "Nginx", "Intercepta chamadas de entrada, gerencia limites de taxa e equilibra nós.")
Container(servico_autenticacao, "Microserviço de Identidade", "Go & OAuth2", "Valida tokens de API de desenvolvedor e escopos.")
Container(servico_transacao, "Livro de Transações", "Java Spring Boot", "Processa pagamentos e gerencia contas do livro.")
ContainerBd(banco_livro, "Armazenamento de Dados do Livro", "CockroachDB", "Implementa esquemas de tabelas distribuídas compatíveis com ACID.")
}
' Roteia fluxos de tráfego de forma limpa entre os destinos internos dos containers
Rel(mercadante, gateway_api, "Envia cargas úteis de pagamento via", "HTTPS/JSON")
Rel_D(gateway_api, servico_autenticacao, "Valida tokens recebidos via", "gRPC")
Rel_D(gateway_api, servico_transacao, "Encaminha ações de checkout para", "gRPC")
Rel_R(servico_transacao, banco_livro, "Persiste entradas do livro via", "SQL/TLS")
@enduml 
Análise de Sintaxe: Ao usar o System_Boundary wrapper de macro, os componentes internos são agrupados de forma limpa dentro de uma caixa de perímetro clara. A macro especializada ContainerDb macro renderiza o armazenamento de dados com um ícone explícito de cilindro de banco de dados, tornando a divisão entre os tempos de execução de computação e as camadas de armazenamento persistente clara de primeira vista.