Neste post, compartilho um pouco da experiência de desenvolver uma aplicação fullstack real com Angular 19, Spring Boot e Docker.
O objetivo não é ensinar passo a passo, mas sim apresentar as decisões técnicas, aprendizados e desafios enfrentados ao longo do projeto.
Ao abordar tópicos como autenticação JWT, arquitetura, integração entre frontend e backend e containerização.
📌 Sobre o projeto
O Mony é uma aplicação web para controle de assinaturas e finanças pessoais. A ideia é oferecer uma forma simples de:
- Cadastrar serviços recorrentes (como Netflix, Spotify, etc.)
- Visualizar todos os gastos mensais
- Ter uma visão clara sobre o orçamento
O foco desse projeto foi estruturar um app fullstack moderno (por isso a escolha do Angular 19) com boas práticas de frontend, backend e containerização com Docker
🔧 Tecnologias utilizadas
- Frontend: Angular 19 + Tailwind CSS v4
- Backend: Java 11 - Spring Boot + Spring Security + JWT + Spring Data JPA
- Banco de dados: PostgreSQL 15
- Containerização: Docker + Docker Compose
🧱 Arquitetura da aplicação
Visão geral da arquitetura lógica da aplicação:
🧬 Modelo de dados
As entidades principais do sistema são MonyUser
, Subscription
, Category
e Address
. Veja como elas se relacionam:
🗂️ Estrutura do Projeto
mony/
├── server/ # Backend Spring Boot
│ └── ... # Controllers, DTOs, Repositories, etc.
├── client/ # Frontend Angular 19
│ └── ... # Features, Shared Modules, Layout
A descrição completa das pastas e suas responsabilidades está disponível no README do repositório.
🧰 Uso do Lombok no backend
Durante o desenvolvimento do backend, utilizei o Project Lombok para reduzir o boilerplate nas classes Java, especialmente nas entidades, DTOs e serviços.
Com anotações como @Getter
, @Setter
, @NoArgsConstructor
, @AllArgsConstructor
e @Builder
, consegui manter o código mais limpo, legível e focado na lógica de negócio, evitando repetições desnecessárias de métodos.
Além de deixar as classes mais enxutas, o uso do Lombok contribuiu para a produtividade e organização geral do projeto.
🔐 Autenticação JWT com Spring Security
Implementei autenticação e autorização com JWT no backend, protegendo todos os endpoints sensíveis. A geração e validação dos tokens são feitas com filtro personalizado no Spring Security.
No frontend, o Angular armazena o token localmente com LocalStorage e utiliza um HTTPInterceptor
para enviá-lo automaticamente em cada requisição autenticada.
💡
Principal
no backendDurante a implementação, tive que decidir como lidar com os dados do usuário autenticado no backend.
Inicialmente, pensei em enviar o ID do usuário em cada requisição ou armazenar algo no
LocalStorage
, mas isso abriria espaço para falhas de segurança.Foi nesse momento que conheci a interface
Principal
do Spring — algo novo pra mim até então. Ela resolvia exatamente o que eu buscava: deixava o backend 100% responsável por identificar o usuário autenticado, com base no JWT.Isso permitiu que cada controller acessasse diretamente o contexto do usuário logado sem depender de nenhuma informação adicional do frontend.
Resultado: código mais limpo, seguro e desacoplado.
A partir disso, todos os controllers que precisam de contexto do usuário simplesmente recebem o Principal
como parâmetro. Com isso, o backend consegue filtrar ou associar dados automaticamente ao usuário autenticado, mantendo a integridade dos dados e a segurança da aplicação.
📦 Docker Compose: backend + frontend + PostgreSQL
Para facilitar o desenvolvimento e isolar os serviços, configurei um ambiente completo com Docker Compose.
services:
- PostgreSQL 15 (banco de dados)
- Spring Boot (backend)
- Angular 19 (frontend)
E com o comando abaixo, toda a aplicação sobe em containers:
docker-compose up --build
🧠 Aprendizados e desafios técnicos
Enquanto desenvolvia o Mony, tive a oportunidade de aprofundar e aplicar conceitos importantes em várias áreas do stack fullstack moderno:
🔷 Frontend (Angular 19)
- Estruturei a aplicação com lazy loading e arquitetura modular por feature, seguindo boas práticas para escalabilidade.
- Usei o Tailwind CSS v4 para estilização rápida, com foco em produtividade e responsividade.
-
Como venho de projetos com versões mais antigas do Angular (8, 11, 14), esse projeto foi também uma oportunidade para aplicar as novidades das versões mais recentes. Entre os destaques:
-
inject()
: substitui a injeção de dependência tradicional via construtor. O código ficou mais limpo e menos verboso, especialmente em componentes simples ou standalone. -
@computed()
: facilita a criação de propriedades derivadas e reativas sem depender derxjs
, tornando o código mais declarativo, previsível e legível. -
@for
e @if: evoluções das diretivas estruturais (*ngFor
,*ngIf
) que tornam o HTML mais moderno e direto, eliminando a necessidade de blocosng-template
e melhorando a performance. -
resource(): uma das features que mais gostei (mesmo ainda sendo experimental). Permite declarar
loader
erequest
de forma reativa e integrada ao ciclo de vida, gerenciando chamadas assíncronas com muito menos código, utilizandosignals
. -
effect(): executa funções automaticamente sempre que um
signal
dependente muda de valor. Usei no serviço de CEP, por exemplo, para atualizar campos dinamicamente conforme o usuário escolhia um estado, assim o DOM respondia instantaneamente.
-
🔶 Backend (Spring Boot)
- Configuração completa do Spring Security com autenticação via JWT
- Implementação de filtros personalizados para validar tokens
- Uso da interface
Principal
para identificar automaticamente o usuário logado sem expor dados no frontend - Mapeamento e relacionamento de entidades com JPA, incluindo um cenário N:N usando
@ManyToMany
com@JoinTable
- Separação clara entre DTOs, entidades, serviços e repositórios
🤝 Conclusão
Você pode conferir o código completo aqui:
🔗 Repositório no GitHub - Mony
📋 Resumo técnico
- ✅ Stack: Angular 19, Spring Boot, PostgreSQL
- 🧠 Auth: JWT + Spring Security +
Principal
- 🐳 Dev: Docker Compose com 3 containers
- 🧰 Extras: Lombok, Tailwind, ng2-charts