🏛️ O que é Arquitetura de Software
A arte de tomar decisões estruturais que resistem ao tempo
Arquitetura de software é o conjunto de decisões estruturais que definem como um sistema é organizado, como seus componentes se comunicam e como ele evolui. Não é sobre linguagens ou frameworks — é sobre trade-offs.
Sem entender arquitetura, você constrói sistemas que funcionam hoje mas quebram amanhã. Ex: O Twitter começou como um monolito Ruby on Rails e precisou reescrever quando atingiu 200M de tweets/dia.
Estrutura vs. Comportamento, Decisões reversíveis vs. irreversíveis, Arquitetura como “as coisas difíceis de mudar depois”
O arquiteto é quem conecta requisitos de negócio a decisões técnicas. Não é o “programador sênior” — é quem garante que o sistema atende necessidades atuais e futuras.
Times sem arquiteto tomam decisões locais que conflitam globalmente. Ex: Na Amazon, antes dos “two-pizza teams”, cada time escolhia tecnologias diferentes e a integração era um pesadelo.
Arquiteto vs. Tech Lead, Decisões técnicas vs. de produto, Comunicação como skill principal
Requisitos funcionais descrevem comportamento (login, checkout). Não-funcionais descrevem qualidades (responder em <200ms, suportar 10k req/s, 99.9% uptime).
A maioria dos problemas em produção vem de requisitos não-funcionais ignorados. Ex: O Healthcare.gov falhou no lançamento porque só testaram funcionalidade, não carga (250k usuários simultâneos vs. 50k planejados).
Performance, Escalabilidade, Disponibilidade, Segurança, Manutenibilidade, Observabilidade
Não existe arquitetura perfeita. Cada escolha favorece uma qualidade em detrimento de outra. CAP theorem é o exemplo clássico: consistência, disponibilidade ou tolerância a partição — escolha dois.
Arquitetos juniores buscam a “melhor” solução. Arquitetos sêniores entendem que toda solução tem custo. Ex: Netflix escolheu eventual consistency para ganhar disponibilidade — seu catálogo pode estar 30s desatualizado, mas nunca fica fora do ar.
CAP Theorem, Latência vs. Throughput, Complexidade vs. Flexibilidade, Custo vs. Performance
Arquitetura boa é aquela que funciona dentro das restrições reais: tamanho do time, budget, prazo, conhecimento técnico existente, regulação.
Microsserviços são elegantes, mas se seu time tem 3 pessoas, é suicídio operacional. Ex: Basecamp (37signals) fatura US$100M/ano com um monolito Ruby on Rails e 70 pessoas. Não precisam de microsserviços.
Conway’s Law, Restrições de time, Budget e timeline, Dívida técnica planejada vs. acidental
Registro formal das decisões arquiteturais, seus motivos e trade-offs aceitos. Inclui diagramas C4, ADRs (Architecture Decision Records) e documentação viva.
Sem documentação, cada novo desenvolvedor redescobre (e frequentemente reverte) decisões anteriores. Ex: O Spotify documenta todas as decisões arquiteturais em ADRs públicos para os times — reduz 40% das discussões repetidas.
Modelo C4, Architecture Decision Records (ADR), Documentação viva vs. estática, Diagramas como comunicação
A história da arquitetura de software é uma progressão de centralizado para distribuído: mainframes → client-server → SOA → microsserviços → serverless → edge computing.
Entender a evolução ajuda a não repetir erros e a avaliar tendências com ceticismo informado. Ex: SOA dos anos 2000 prometia tudo que microsserviços prometem hoje — e falhou pelas mesmas razões quando mal implementada.
Mainframes e batch, Client-server, SOA e ESB, Microsserviços, Serverless e FaaS, Edge computing
🏢 Estilos Arquiteturais
Monolito, microsserviços, serverless — quando usar cada um
Aplicação onde todo o código roda como uma única unidade deployável. Um processo, um banco, um deploy. É o estilo mais simples e frequentemente o mais eficiente para começar.
95% dos projetos deveriam começar como monolito. Ex: Shopify processa US$175B/ano em GMV com um monolito Ruby on Rails. Eles modularizaram internamente sem quebrar em microsserviços.
Single deployable unit, Simplicidade operacional, Acoplamento interno, Quando o monolito vira problema
Monolito com limites internos claros entre módulos. Cada módulo tem sua interface pública, seus dados privados, mas tudo roda no mesmo processo.
É o stepping stone natural entre monolito e microsserviços — ganha modularidade sem complexidade distribuída. Ex: O Basecamp usa monolito modular. Cada “domínio” (projects, messages, files) é um módulo independente dentro do mesmo Rails app.
Bounded contexts internos, Interfaces entre módulos, Dados privados por módulo, Migração gradual
Cada serviço é independente: deploy próprio, banco próprio, equipe própria. Comunicação via API ou mensageria.
Microsserviços resolvem problemas organizacionais, não técnicos. Se seu time não precisa de deploys independentes, microsserviços são overhead. Ex: Amazon migrou para microsserviços quando tinha 1000+ devs e deploys bloqueavam uns aos outros. Não fez isso com 50 devs.
Independência de deploy, Database per service, API Gateway, Service mesh, Complexidade operacional exponencial
Funções que executam sob demanda, sem servidor dedicado. AWS Lambda, Cloudflare Workers, Vercel Functions.
Ideal para workloads imprevisíveis e spiky. Ex: A Coca-Cola usa Lambda para processar vendas de máquinas automáticas — 0 custo quando ninguém compra, escala instantânea no horário de almoço.
Functions as a Service (FaaS), Cold start, Limites de execução, Vendor lock-in, Stateless by design
Componentes se comunicam através de eventos assíncronos. Um publica, vários consomem. Desacoplamento máximo.
EDA é o padrão natural para sistemas que precisam reagir a mudanças em tempo real. Ex: O Uber usa EDA para coordenar corridas — quando um motorista aceita, eventos disparam atualização do mapa, notificação ao passageiro, cálculo de rota e billing, tudo em paralelo.
Publish/subscribe, Event sourcing, CQRS, Message brokers (Kafka, RabbitMQ, Redis Streams), Eventual consistency
Sistema dividido em camadas com responsabilidades distintas: apresentação, lógica de negócio, acesso a dados. Cada camada só fala com a adjacente.
É o padrão mais usado em aplicações web tradicionais e o ponto de partida para entender separação de concerns. Ex: A maioria dos apps Django/Rails segue MVC — controller (apresentação), model (dados), service layer (negócio).
Presentation layer, Business logic layer, Data access layer, MVC/MVP/MVVM, Dependency rule
O core da aplicação (regras de negócio) não depende de framework, banco ou API externa. Tudo é plugável via ports e adapters.
Permite trocar banco, framework ou API sem reescrever lógica de negócio. Ex: O Nubank usa Clean Architecture — migraram de Datomic para PostgreSQL em alguns serviços sem tocar na lógica de negócio.
Ports and Adapters, Dependency Inversion, Use Cases, Domain-centric design, Testabilidade
⚡ Princípios de Design
SOLID, DRY, KISS e os padrões que todo arquiteto deve conhecer
Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion. São princípios de design orientado a objetos que guiam decisões arquiteturais.
Código que viola SOLID se torna impossível de manter. Ex: Uma classe PaymentProcessor que também envia emails, gera PDFs e atualiza inventário viola SRP — quando muda a regra de email, você arrisca quebrar pagamentos.
SRP, OCP, LSP, ISP, DIP com exemplos práticos de violação e correção
Don’t Repeat Yourself, Keep It Simple Stupid, You Ain’t Gonna Need It. Três mantras contra over-engineering.
DRY mal aplicado gera abstrações prematuras piores que duplicação. Ex: Copiar 3 linhas de validação em 2 controllers é melhor que criar um ValidationFramework que 2 pessoas vão usar.
Duplicação de conhecimento vs. duplicação de código, Abstrações prematuras, When to generalize
Padrões GoF (Gang of Four) e padrões modernos: Factory, Strategy, Observer, Repository, Dependency Injection.
Patterns são vocabulário compartilhado. Quando você diz “usa Strategy aqui”, o time inteiro entende. Ex: Stripe usa Strategy pattern para processadores de pagamento — adicionar Pix foi criar um novo strategy, sem tocar no core.
Creational (Factory, Builder), Structural (Adapter, Facade), Behavioral (Strategy, Observer, Command)
Acoplamento é o grau de dependência entre módulos. Coesão é o grau em que elementos de um módulo pertencem juntos. O ideal: baixo acoplamento, alta coesão.
Módulos muito acoplados cascateiam falhas. Ex: Se seu módulo de auth depende diretamente do módulo de billing, uma mudança no billing pode derrubar o login.
Tight vs. loose coupling, Functional vs. temporal cohesion, Metrics de acoplamento, Refactoring strategies
Dividir o sistema em partes que lidam com uma preocupação específica. Frontend não sabe de banco. API não sabe de UI. Banco não sabe de regra de negócio.
Violação gera código spaghetti onde tudo depende de tudo. Ex: SQL no template HTML (violação clássica que ainda acontece) — muda o layout, quebra a query.
Vertical vs. horizontal slicing, Cross-cutting concerns, Aspect-oriented design, Layered vs. feature-based organization
Aplicação do SRP em nível arquitetural. Cada serviço/módulo deve ter apenas uma razão para mudar, pertencendo a um único domínio de negócio.
Serviços que fazem muita coisa se tornam mini-monolitos distribuídos. Ex: Um “UserService” que gerencia auth, perfil, preferências e billing é um monolito disfarçado de microsserviço.
Bounded Context, Domain ownership, Razões para mudança, Decomposição por domínio vs. por camada técnica
Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações.
Sem inversão de dependência, seu core de negócio fica preso ao framework e ao banco. Ex: Sua lógica de “aprovar pedido” não deve importar se usa PostgreSQL ou MongoDB — injete a interface, não a implementação.
Dependency Injection, Interface-based design, Plugin architecture, Testabilidade como benefício colateral
🔒 Qualidade e Atributos de Qualidade
Performance, segurança, disponibilidade — os -ilities que definem o sucesso
Tempo de resposta (latência), quantidade de requisições processadas (throughput) e uso eficiente de recursos. Performance é sobre atender SLAs, não sobre ser o mais rápido possível.
Cada 100ms a mais no carregamento reduz conversão em 1% (Amazon). Performance impacta diretamente receita.
P50/P95/P99 latency, Throughput vs. latency, Profiling e bottlenecks, Caching strategies (Redis, CDN, browser)
Capacidade de lidar com aumento de carga (usuários, dados, transações) sem degradação significativa.
Sistemas que não escalam forçam reescritas caras. Ex: O Instagram escalou de 0 a 30M de usuários em 2 anos com apenas 3 engenheiros — graças a decisões arquiteturais certas (PostgreSQL + Redis + memcached).
Vertical vs. horizontal scaling, Stateless services, Database sharding, Read replicas, Load balancing
Proteção contra acesso não autorizado, manipulação de dados e ataques. Inclui autenticação, autorização, criptografia e auditoria.
Uma brecha de segurança pode encerrar uma empresa. Ex: O breach da Equifax (2017) expôs dados de 147M de pessoas por um patch de Apache Struts não aplicado — custou US$700M em multas.
OWASP Top 10, Zero Trust Architecture, JWT/OAuth2, Encryption at rest and in transit, Principle of Least Privilege
Percentual de tempo que o sistema está operacional. 99.9% = 8.7h de downtime/ano. 99.99% = 52min/ano.
SLAs definem o negócio. Ex: AWS S3 prometia 99.99% e quando caiu por 4h em 2017, derrubou metade da internet junto (Netflix, Slack, Trello dependiam dele).
SLA/SLO/SLI, Redundância, Failover, Health checks, Circuit breaker pattern, Chaos engineering
Facilidade de entender, modificar e corrigir o sistema. Inclui legibilidade, modularidade, testabilidade e documentação.
Você gasta 10x mais tempo mantendo código do que escrevendo. Ex: O Google estima que 70% do custo de software está em manutenção, não em desenvolvimento inicial.
Cyclomatic complexity, Code review culture, Refactoring contínuo, Technical debt management, Readability > cleverness
Capacidade de entender o estado interno do sistema através de outputs externos: logs, métricas e traces. Os “3 pilares” da observabilidade.
Em sistemas distribuídos, bugs reproduzíveis em local são a exceção. Ex: O Stripe usa distributed tracing para acompanhar cada requisição de pagamento por 15+ serviços — sem isso, debugar levaria horas em vez de minutos.
Logs estruturados, Métricas (Prometheus/Grafana), Distributed tracing (Jaeger/OpenTelemetry), Alerting inteligente, Dashboards operacionais
O grau em que o sistema permite ser testado automaticamente em diferentes níveis: unitário, integração, end-to-end, contrato.
Se testar é difícil, o time para de testar. Ex: O Nubank tem 90%+ de cobertura em Clojure porque a arquitetura facilita — funções puras, imutabilidade, injeção de dependência everywhere.
Test pyramid, Contract testing, Property-based testing, Mutation testing, Test doubles (mocks, stubs, fakes)
🌐 Comunicação entre Sistemas
REST, GraphQL, gRPC, mensageria — como sistemas conversam
Architectural style baseado em recursos (URLs), verbos HTTP (GET, POST, PUT, DELETE) e representações (JSON). Stateless por design.
REST é a lingua franca de APIs web. ~83% das APIs públicas são REST. Ex: A API do GitHub é REST pura — cada recurso (/repos, /issues, /pulls) é um endpoint previsível.
Resources, HTTP verbs, Status codes, HATEOAS, Versionamento, Rate limiting
Query language para APIs onde o cliente define a estrutura da resposta. Uma única URL, múltiplas queries possíveis.
Resolve over-fetching e under-fetching de REST. Ex: O app do Facebook carregava 15+ endpoints REST para montar o feed. Com GraphQL, uma query retorna exatamente os dados necessários — reduziu uso de dados mobile em 40%.
Schema-first, Queries e Mutations, Resolvers, N+1 problem, Fragments, Subscriptions para real-time
Framework RPC do Google usando Protocol Buffers (protobuf) e HTTP/2. Fortemente tipado, com geração automática de código.
Quando latência entre serviços importa. Ex: O Google usa gRPC internamente para comunicação entre microsserviços — 10x mais rápido que REST+JSON em cenários de alta frequência.
Protocol Buffers, HTTP/2 streaming, Strongly typed contracts, Code generation, Ideal para service-to-service
Comunicação via mensagens em filas ou tópicos. O produtor não espera resposta. Kafka, RabbitMQ, SQS, Redis Streams.
Desacopla sistemas e absorve picos de carga. Ex: O Mercado Livre processa 1M+ de transações/dia via Kafka — o checkout não espera o email de confirmação; publica um evento e segue.
Queue vs. Topic, At-least-once vs. exactly-once, Dead letter queue, Backpressure, Idempotência
HTTP callbacks — um sistema notifica outro quando algo acontece, enviando um POST com dados do evento. Inversão do modelo poll.
Webhooks são a espinha dorsal de integrações modernas. Ex: Stripe, GitHub, Slack — todos usam webhooks. Quando um pagamento é aprovado no Stripe, seu sistema recebe um POST instantâneo em vez de ficar polling.
Retry policies, Signature verification (HMAC), Idempotency keys, Timeout handling, n8n como webhook receiver
Conexão bidirecional persistente (WebSocket) ou stream unidirecional do servidor (SSE). Para dados que mudam constantemente.
Quando polling não é suficiente. Ex: O Figma usa WebSockets para colaboração em tempo real — cada cursor, cada mudança de shape é sincronizada em <50ms entre todos os colaboradores.
Full-duplex vs. half-duplex, Connection management, Heartbeat, Scaling WebSockets, SSE como alternativa mais simples
API Gateway é o ponto de entrada único para APIs externas (Kong, AWS API Gateway). Service Mesh gerencia comunicação interna (Istio, Linkerd).
Sem gateway, cada serviço reimplementa auth, rate limiting e logging. Ex: A Netflix usa Zuul como API Gateway — 2B+ requests/dia passam por ele antes de chegar aos microsserviços.
Reverse proxy, Rate limiting, Circuit breaker, mTLS, Sidecar pattern, Observability automática