Introdução ao modelo C4 para documentação de arquitetura em níveis

1. O que é o modelo C4 e por que ele surgiu

Por décadas, a documentação de arquitetura de software foi dominada por diagramas monolíticos e estáticos que rapidamente se tornavam obsoletos. Equipes gastavam semanas criando diagramas UML complexos que, após o primeiro deploy, já não refletiam a realidade do sistema. Essa crise de documentação levou Simon Brown, em 2011, a criar o modelo C4 — uma abordagem hierárquica para representar arquiteturas de software em quatro níveis de abstração.

O nome C4 vem dos quatro níveis: Contexto, Container, Componente e Código. O princípio fundamental é que cada nível atende a um público-alvo específico, do executivo ao desenvolvedor, usando uma notação simples baseada em caixas e setas. Diferente de padrões como UML 2.0, o C4 não exige simbologia complexa — você pode desenhar diagramas C4 até mesmo em um quadro branco.

2. Nível 1: Diagrama de Contexto (Visão do Sistema)

O diagrama de contexto é o nível mais abstrato. Ele mostra o sistema como uma caixa-preta, destacando apenas seus relacionamentos com atores externos — usuários, sistemas legados, serviços terceiros.

Exemplo prático: Sistema de e-commerce

+-------------------+       +-------------------+
|                   |       |                   |
|   Cliente Web     |------>|   Sistema de      |
|   (usuário)       |       |   E-commerce      |
|                   |       |   [Sistema em     |
+-------------------+       |    desenvolvimento]|
                            |                   |
                            +--------+----------+
                                     |
                                     v
                            +-------------------+
                            |                   |
                            |   Gateway de      |
                            |   Pagamento       |
                            |   (sistema externo)|
                            |                   |
                            +-------------------+

Boas práticas:
- Mantenha entre 3 a 7 elementos externos
- Use setas direcionais para indicar fluxo de dados
- Evite qualquer detalhe interno do sistema

3. Nível 2: Diagrama de Container (Visão de Alto Nível)

No C4, "container" não significa Docker — é qualquer unidade executável ou armazenável: aplicações web, bancos de dados, filas de mensagens, microsserviços. Este nível mostra como os containers se comunicam.

Exemplo prático: Decomposição do sistema de e-commerce

+-------------------+     HTTP/HTTPS     +-------------------+
|                   |------------------->|                   |
|   Single Page App |                    |   API REST        |
|   (React)         |<-------------------|   (Node.js)       |
|                   |     JSON           |                   |
+-------------------+                    +--------+----------+
                                                   |
                                                   | JDBC
                                                   v
                                          +-------------------+
                                          |                   |
                                          |   Banco de Dados  |
                                          |   PostgreSQL      |
                                          |                   |
                                          +-------------------+

Elementos representados:
- Frontend (SPA): Container React que consome APIs
- Backend (API): Container Node.js com lógica de negócio
- Banco: Container PostgreSQL para persistência
- Protocolos: HTTP/HTTPS para comunicação, JDBC para banco

4. Nível 3: Diagrama de Componente (Visão Interna do Container)

Aqui entramos no detalhamento de um container específico. Cada container é decomposto em componentes de software — módulos, serviços, controladores.

Exemplo prático: Detalhamento do container "API REST"

+------------------------------------------------------+
|                  API REST (Node.js)                   |
|                                                      |
|  +----------------+  +----------------+              |
|  |  Auth Service  |  |  Product       |              |
|  |  (JWT + OAuth) |  |  Service       |              |
|  +----------------+  +----------------+              |
|         |                     |                       |
|         v                     v                       |
|  +----------------+  +----------------+              |
|  |  User          |  |  Catalog       |              |
|  |  Repository    |  |  Repository    |              |
|  +----------------+  +----------------+              |
|         |                     |                       |
|         +---------------------+                       |
|                   |                                   |
|                   v                                   |
|  +------------------------------------------------+  |
|  |           Database Access Layer                 |  |
|  |           (ORM - Prisma)                        |  |
|  +------------------------------------------------+  |
+------------------------------------------------------+

Responsabilidades:
- Auth Service: Autenticação e autorização
- Product Service: Regras de negócio para catálogo
- Repositories: Abstração de persistência
- Database Access Layer: Mapeamento objeto-relacional

Quando parar: Se o diagrama ficar com mais de 15 componentes, considere dividir em múltiplos diagramas.

5. Nível 4: Diagrama de Código (Visão de Implementação)

O último nível detalha componentes individuais usando diagramas UML ou equivalentes. É o nível mais propenso à obsolescência.

Exemplo prático: Classe UserService

+-----------------------------------+
|          UserService               |
+-----------------------------------+
| - userRepository: UserRepository  |
| - emailService: EmailService      |
+-----------------------------------+
| + createUser(dto: CreateUserDTO)  |
| + findByEmail(email: string)      |
| + deactivateUser(id: UUID)        |
+-----------------------------------+

Limitações e alternativas:
- Risco: Diagramas de código desatualizam em dias
- Alternativa: Use anotações JSDoc/JavaDoc com geradores automáticos
- Recomendação: Só crie diagramas de código para componentes críticos ou complexos

6. Notação e ferramentas para criar diagramas C4

Notação padrão (Structurizr):
- Caixas azuis para pessoas, laranja para sistemas, verde para containers
- Setas tracejadas para dependências, contínuas para fluxo de dados

Ferramentas recomendadas:

Ferramenta Tipo Ideal para
Structurizr DSL + renderizador Equipes que versionam diagramas
PlantUML Código → diagrama Integração com Markdown
Draw.io GUI Rascunhos rápidos
Mermaid Markdown Documentação inline

Exemplo de diagrama como código (Structurizr DSL):

workspace {
    model {
        user = person "Cliente" "Usuário do sistema"
        system = softwareSystem "E-commerce" "Sistema de vendas"
        user -> system "Usa"
    }
    views {
        systemContext system "Contexto" {
            include *
            autoLayout
        }
    }
}

7. Integração do C4 com o ciclo de vida do software

Para que os diagramas C4 não se tornem artefatos mortos, integre-os ao pipeline de desenvolvimento:

Em CI/CD:
- Use structurizr-cli para validar diagramas em cada commit
- Gere diagramas automaticamente a partir de arquivos DSL versionados
- Publique em um servidor interno (Structurizr on-premises)

Em code reviews:
- Inclua o diagrama de contexto no README do repositório
- Exija atualização do diagrama de container quando houver mudanças na arquitetura
- Use ADRs (Architecture Decision Records) para documentar decisões referenciando os diagramas C4

Relação com outros artefatos:
- ADRs: Cada decisão arquitetural deve referenciar o nível C4 afetado
- Documentação de API: O diagrama de container mostra quais APIs existem
- Guias de estilo: Defina cores e notações padrão para toda a equipe


Referências