🚀 Do Zero ao C4: Construindo a Arquitetura de uma API de Supermercado
Cláudio Filipe Lima Rapôso

Cláudio Filipe Lima Rapôso @sertaoseracloud

About: At NTT DATA Europe & Latam, my role as a Systems Architect harnesses the power of Typescript, Java and Phyton to creating robust and scalable solutions.

Location:
Brazil
Joined:
Jan 10, 2025

🚀 Do Zero ao C4: Construindo a Arquitetura de uma API de Supermercado

Publish Date: Jun 5
2 2

Documentar a arquitetura de um sistema de software é fundamental para que todos os envolvidos entendam como as partes se conectam. O C4 Model (ou C4 Framework) é uma forma de visualizar e descrever a arquitetura em quatro níveis de abstração: Contexto, Container, Componente e Código. Criado por Simon Brown, esse modelo surgiu para resolver problemas de documentações confusas e difíceis de manter, trazendo uma visão mais clara da arquitetura em múltiplos níveis, adequada a diferentes públicos (desenvolvedores, arquitetos, stakeholders etc.). Neste artigo, vamos explicar cada uma das quatro camadas do C4 Model em linguagem simples, voltada para iniciantes, usando como exemplo uma API de supermercado escrita em TypeScript.

Você vai aprender o que representa cada nível (do grande panorama ao código) e como eles se aplicam no exemplo prático de uma aplicação de supermercado online. Vamos lá!


Nível 1️⃣: Diagrama de Contexto (Visão de Contexto do Sistema)

Nível 1:Diagrama de Contexto

No nível mais alto de abstração temos o Contexto. O Diagrama de Contexto mostra, em um único quadro geral, o sistema de software e como ele se relaciona com o mundo externo – isto é, quem utiliza o sistema e com quais outros sistemas ele interage. Em outras palavras, é uma visão macro: ideal para entender quem são os atores (usuários ou outros sistemas) e como o seu sistema se encaixa no ecossistema maior.

Como isso se aplica à nossa API de supermercado? Imagine que estamos desenvolvendo uma plataforma online de supermercado. No diagrama de contexto, nosso sistema principal seria a “Aplicação Supermercado Online” (a API que estamos construindo). Os atores externos podem incluir, por exemplo, o Cliente (usuário final que acessa o aplicativo para fazer compras) e um Administrador (funcionário do supermercado gerenciando produtos e pedidos). Além das pessoas, também podem existir sistemas externos interagindo com a nossa API. No caso do supermercado, poderíamos ter:

  • Um sistema de pagamento de terceiros (por exemplo, um serviço de pagamento via cartão de crédito) que a nossa API utiliza para processar compras.
  • Um serviço de e-mail ou notificações utilizado para enviar confirmações de pedido aos clientes.

No diagrama de contexto, representaríamos cada pessoa (cliente, administrador) como um ator fora do sistema, e cada sistema externo (gateway de pagamento, serviço de e-mail) como um elemento externo. Nossa API de supermercado ficaria ao centro, demonstrando as interações: clientes se comunicam com a API (por meio do app ou site), e a API por sua vez se comunica com os serviços externos necessários. Tudo resumido em um desenho simples, sem entrar em detalhes internos — é alto nível e fácil de entender, ideal para mostrar a visão geral a qualquer um, inclusive membros não técnicos da equipe.

(Por exemplo, pense em um cliente fazendo login no aplicativo do supermercado e comprando um item: o diagrama de contexto mostraria o cliente → nosso sistema API supermercado → sistema de pagamento, evidenciando esses relacionamentos básicos. O Exemplo abaixo mostra o diagrama criado seguindo o framework)

C4 Diagrams Diagrama de Contexto

C4 Diagrams Diagrama de Contexto legendas


Nível 2️⃣: Diagrama de Container (Visão dos Contêineres do Sistema)

Nível 2: Diagrama de Container

Descendo um nível de detalhe, temos o Container. Aqui, "container" não se refere a container Docker especificamente, mas a unidades executáveis ou de armazenamento que compõem o sistema – aplicações, serviços, bases de dados, etc. O Diagrama de Container mostra os principais contêineres de software que compõem o sistema e como eles se comunicam, incluindo as tecnologias usadas. Em resumo, essa visão detalha a arquitetura interna de alto nível: quais aplicações e bancos de dados existem e como interagem entre si.

Aplicando ao exemplo do supermercado: Dentro da nossa “Aplicação Supermercado Online”, provavelmente há vários contêineres trabalhando juntos. Podemos identificar pelo menos os seguintes:

  • Backend API do Supermercado – O nosso serviço principal, implementado em Node.js/TypeScript (por exemplo, usando Express ou NestJS). Este container expõe endpoints HTTP (REST) que permitem realizar login, listar produtos, criar pedidos, etc.
  • Banco de Dados do Supermercado – Um contêiner de armazenamento de dados (pode ser um banco relacional PostgreSQL, um NoSQL como MongoDB, etc.) onde ficam guardadas informações de produtos, clientes, pedidos, etc.
  • Aplicação Front-end – Embora o foco seja a API, vale lembrar que os clientes interagem através de uma interface. Poderíamos ter um contêiner para um aplicativo Web (por exemplo, uma aplicação React ou Angular rodando no navegador) e/ou um aplicativo móvel que consome a API. Esses front-ends são contêineres separados que se comunicam com a API via HTTP.

No diagrama de container, desenharíamos a API como um contêiner (indicando a tecnologia, ex: “Node.js/Express API”), o Banco de Dados como outro (ex: “MongoDB Database”) e o Front-end como outro (ex: “Aplicativo Web React”). Indicaríamos as comunicações: o front-end se conecta à API (chamadas REST), a API consulta/escreve no banco de dados (conexão de banco), e a API também se conecta ao serviço de pagamento externo (chamada API externa). Cada contêiner também mostra sua responsabilidade principal. Por exemplo, a API cuida da lógica de negócio, o banco armazena dados, o front-end exibe as funcionalidades ao usuário.

Essa visão de containers deixa claro como o sistema está estruturado em termos de deploy – quem roda onde e falando com quem. Novamente, ainda não vemos detalhes de código ou componentes internos, mas já sabemos, por exemplo, que nossa API de supermercado consiste em um backend + database, e que existe um front-end consumindo, mais integrações externas. Isso ajuda arquitetos e desenvolvedores a entenderem a divisão de responsabilidades entre serviços (cada contêiner com seu papel) e as tecnologias em jogo antes de mergulharmos no código.

(No diagrama de container abaixo do nosso supermercado: veríamos algo como um retângulo para “API Supermercado (Node/TS)”, conectado a um banco “DB Supermercado (Postgres)”, e a um retângulo “App Web Cliente (React)”, além de uma seta da API para um bloco externo “Gateway de Pagamento”.)

C4 Diagrams Diagrama de Container

C4 Diagrams Diagrama de Container legendas


Nível 3️⃣: Diagrama de Componentes (Visão Interna de Componentes)

Nível 3: Diagrama de Componentes

O terceiro nível foca dentro de um contêiner específico, revelando os blocos de construção internos – os Componentes de software e suas interações. Um Diagrama de Componentes mostra os principais componentes de um container e como eles se relacionam. Podemos pensar em componentes como agregados de classes ou módulos com uma responsabilidade específica dentro da aplicação (por exemplo: um controlador MVC, um serviço, um repositório de dados, etc.). Essa visão é especialmente útil para desenvolvedores, pois aproxima da implementação sem chegar ao código-fonte detalhado.

No caso da API de supermercado (container de Backend): Vamos ampliar a nossa API Node/TypeScript para ver seus componentes internos. Suponha que implementamos a API seguindo uma arquitetura em camadas (por exemplo, modelo MVC ou similar). Poderíamos ter componentes como:

  • Controller de Produtos – responsável por receber as requisições relacionadas a produtos (listar produtos, detalhes de produto, adicionar novo produto, etc.) e retornar as respostas adequadas.
  • Controller de Pedidos – responsável pelas requisições de criação de pedidos, atualização de status, listagem de pedidos do cliente, etc.
  • Serviço de Pagamento – componente que encapsula a lógica de integração com o sistema de pagamento externo. Por exemplo, o Controller de Pedidos chamará este serviço para processar o pagamento de uma compra.
  • Serviços de Domínio – camadas de negócio associadas a cada entidade principal. Por exemplo, um ProductService contendo regras de negócios de produtos (verificar estoque, aplicar promoções) e um OrderService para regras de pedidos (calcular total, verificar disponibilidade, coordenar pagamento). Esses serviços são chamados pelos controllers.
  • Repositórios (Data Access) – componentes responsáveis por interagir com o banco de dados. Por exemplo, um ProdutoRepository para operações CRUD de produtos na base de dados e um PedidoRepository para pedidos. Os serviços de domínio utilizam os repositórios para acessar os dados.

Cada um desses componentes é uma parte do código com uma responsabilidade clara. No diagrama de componentes da API, visualizaríamos, por exemplo, que o PedidoController utiliza o OrderService, que por sua vez conversa com o PedidoRepository e o Serviço de Pagamento. Também veríamos o ProdutoController conversando com ProductService e este com ProdutoRepository, e assim por diante. As relações (setas no diagrama) indicam chamadas ou dependências entre componentes. Essa visão ajuda a equipe a entender como o código está organizado internamente em módulos e camadas, antes mesmo de olhar para a implementação. Em resumo, no nível de componente estamos mapeando as partes da aplicação dentro de um contêiner – no nosso caso, dentro da API do supermercado – e vendo como essas partes colaboram para realizar as funcionalidades. É um nível ótimo para desenvolvedores discutirem design interno da aplicação, divisão em módulos, responsabilidades de classes, etc..

(Continuando nosso exemplo, o diagrama de componentes deixaria claro, por exemplo: “PedidoController -> OrderService -> (PedidoRepository + ServiçoPagamento) -> GatewayPagamento externo”, mostrando o fluxo interno quando um pedido é criado.)

C4 Diagrams Diagrama de Componentes

C4 Diagrams Diagrama de Componentes legendas


Nível 4️⃣: Diagrama de Código (Visão do Código/Implementação)

Finalmente, o quarto nível é o mais detalhado: a visão de Código ou implementação. Nem sempre é necessário chegar a esse nível na documentação, pois ele mostra os detalhes de classes, métodos e código-fonte – algo que, muitas vezes, os próprios desenvolvedores obtêm diretamente do repositório. De fato, o uso do diagrama de código é opcional, recomendado apenas se for útil para compreensão, já que geralmente pode ser gerado pelas ferramentas ou IDEs quando preciso. No C4 Model, esse nível costuma ser representado por diagramas UML de classes ou sequências, mostrando como um componente é realizado internamente por classes e suas relações.

No exemplo da nossa API de supermercado: Se quisermos detalhar ainda mais o componente de Pedidos, poderíamos ilustrar com um diagrama ou trecho de código como as classes estão implementadas. Vamos supor que o componente OrderService/PedidoController é implementado com duas classes em TypeScript: uma classe PedidoController e uma classe PedidoService, e que temos também uma classe PagamentoService e PedidoRepository.

Vamos mostrar como é a interação entre essas classes dentro do componente de Pedidos:

Nível 4: Diagrama de Código

No diagrama acima, vemos como as classes colaboram dentro do componente de Pedidos: o PedidoController recebe a requisição HTTP e delega a criação do pedido ao PedidoService. O PedidoService, por sua vez, utiliza o PagamentoService para processar o pagamento do pedido e o PedidoRepository para salvar os dados no banco. Essa implementação corresponde exatamente ao que havíamos descrito no diagrama de componentes. Se fôssemos desenhar um diagrama de classes UML para este componente, teríamos caixas representando essas classes (PedidoController, PedidoService, etc.) e setas indicando que PedidoController depende de PedidoService, que por sua vez depende de PagamentoService e PedidoRepository.

O importante sobre a camada de Código é notar que ela reflete o código-fonte real. Muitas vezes, times ágeis não mantêm diagramas de código atualizados porque o código em si já é a fonte de verdade – por isso esse nível é opcional. Mas em treinamentos ou documentação de referência, pode ser útil mostrar um exemplo de código ou diagrama de classe para ilustrar como um determinado componente foi implementado. No nosso exemplo, conseguimos visualizar em TypeScript exatamente como a lógica de pedidos é estruturada, o que ajuda novos desenvolvedores a compreenderem detalhes da implementação.


📚 Conclusão

O C4 Model nos permite descrever a arquitetura de um sistema em diferentes níveis de granularidade, do panorama geral até os detalhes finos do código. Cada nível atende a um propósito e a um público: o contexto para entendermos o sistema no mundo (útil para apresentar a ideia a stakeholders não técnicos), os containers para vermos as partes do sistema e tecnologias (útil para arquitetos e devs planejando a estrutura), os componentes para detalhar a construção interna de cada parte (útil para desenvolvedores implementando funcionalidades), e o código para aqueles que precisam do detalhe máximo (geralmente usado apenas quando necessário). Essa abordagem hierárquica possibilita contar diferentes “histórias” da arquitetura para diferentes audiências de forma clara e estruturada, sem sobrecarregar ninguém com informação de menos ou em excesso.

Concluimos que documentar sua aplicação de supermercado (ou qualquer outro sistema) usando o C4 Model garante que você e seu time tenham uma compreensão compartilhada da arquitetura em todos os níveis – facilitando a comunicação, a manutenção e a evolução do software. Para um desenvolvedor júnior, essa técnica oferece um mapa valioso: desde entender onde seu código se encaixa no contexto do negócio até ver como as partes do sistema trabalham juntas. Aproveite esses quatro níveis de perspectiva para construir sistemas mais bem documentados e mais fáceis de entender por todos!

Claro! Para aprofundar seu conhecimento sobre o C4 Model e a utilização do Structurizr DSL, especialmente aplicando esses conceitos a uma API de supermercado em TypeScript, recomendo as seguintes leituras e recursos:


📘 Leitura Recomendada

  1. Documentação Oficial do Structurizr DSL
    A documentação oficial oferece uma visão abrangente sobre como modelar arquiteturas de software utilizando o Structurizr DSL, baseado no C4 Model.
    🔗 Structurizr DSL Documentation

  2. C4 Model – Site Oficial
    O site oficial do C4 Model fornece uma introdução detalhada aos quatro níveis de abstração (Contexto, Contêiner, Componente e Código) e exemplos de diagramas.
    🔗 C4 Model

  3. Cookbook do Structurizr DSL
    Este guia prático apresenta exemplos e melhores práticas para criar diagramas utilizando o Structurizr DSL, incluindo estilos, temas e visualizações personalizadas.
    🔗 Structurizr DSL Cookbook

  4. Exemplos Práticos no GitHub
    Repositório com exemplos de modelagem de arquiteturas de software usando o C4 Model e o Structurizr DSL, incluindo diferentes níveis de diagramas.
    🔗 godatadriven/c4-model-example

  5. Artigo: "Getting Started with the Structurizr DSL" por Simon Brown
    Neste artigo, o criador do C4 Model apresenta uma introdução prática ao Structurizr DSL, demonstrando como definir modelos e visualizações.
    🔗 Getting Started with the Structurizr DSL

  6. Tutorial em Vídeo: "How to Create C4 Diagrams with Code"
    Este vídeo tutorial demonstra como criar diagramas C4 utilizando o Structurizr DSL, abordando desde a instalação até a geração de diagramas.
    🔗 YouTube – How to Create C4 Diagrams with Code


🛠️ Ferramentas e Recursos Adicionais

  • Structurizr Lite: Versão local do Structurizr que permite visualizar e editar diagramas definidos com o DSL. Ideal para testes e desenvolvimento local.
    🔗 Structurizr Lite

  • Structurizr CLI: Interface de linha de comando para trabalhar com workspaces do Structurizr, permitindo push/pull de modelos e exportação para outros formatos.
    🔗 Structurizr CLI(Structurizr)

  • Editor Online do Structurizr DSL: Editor baseado na web para escrever e visualizar modelos DSL sem necessidade de instalação local.
    🔗 Structurizr DSL Editor


Curtiu?

Se quiser trocar ideia sobre IA, cloud e arquitetura, me segue nas redes:

Publico conteúdos técnicos direto do campo de batalha. E quando descubro uma ferramenta que economiza tempo e resolve bem, como essa, você fica sabendo também.


Comments 2 total

Add comment