Encurtador de URLs
Uma aplicação pequena e completa com Angular e Spring Boot. Você cola uma URL longa, recebe uma curta, e a API redireciona quem abrir o link.
Fiz sozinho.

O problema
Eu queria uma aplicação pequena que cobrisse o caminho inteiro de uma requisição web: um campo no navegador, uma API REST e um banco relacional. Um encurtador de URLs tem esse formato, com uma tabela e dois endpoints.
Decisões
DTO e mapper numa aplicação pequena
A primeira versão funcional passava a entidade entre as camadas. Depois que controller, service e banco estavam funcionando, criei um DTO em record e um mapper MapStruct, para separar o contrato da API da tabela. Com uma tabela só isso acrescenta arquivos, mas tira o modelo de persistência da camada HTTP.
Quatro letras aleatórias como código
O service gera quatro letras minúsculas aleatórias, o que dá links curtos e legíveis e 456.976 códigos possíveis. O custo são as colisões: o banco recusa um código repetido pela restrição de unicidade, mas o service ainda não tenta de novo, e o README deixa isso registrado.
Esquema gerenciado pelo Hibernate
Deixei o Hibernate criar a tabela com ddl-auto=update em vez de escrever migrações. Com uma tabela só e nenhum dado em produção, a instalação se resume a um CREATE DATABASE, ao custo de não ter histórico versionado do esquema.
O que eu fiz
- Uma API REST em Spring Boot 4 com Java 17 e dois endpoints: um que cria o código curto e outro que redireciona com 302 ou responde 404.
- Uma entidade JPA e um repository do Spring Data com uma query derivada que busca o link pelo código, com restrição de unicidade na coluna do código no PostgreSQL.
- Um record Java como DTO e um mapper MapStruct entre ele e a entidade, para que o controller receba e devolva o DTO e nunca o modelo de persistência.
- Geração de código com o RandomStringGenerator do Apache Commons Text e uma checagem que coloca https:// em endereços sem esquema.
- Um componente em Angular 21 que envia o endereço com HttpClient e mostra o resultado por meio de um signal, com estilo em Tailwind CSS 4.
- Um README que documenta instalação, endpoints, configuração, testes e os limites atuais da aplicação.
Como funciona
A página em Angular liga o endereço digitado a um campo de texto com ngModel. Quando a pessoa clica em Shorten Url, o HttpClient manda o valor para POST /urlshortener/post. O service em Spring Boot coloca https:// quando o endereço vem sem esquema, gera um código de quatro letras minúsculas com o Apache Commons Text e salva o endereço e o código numa tabela do PostgreSQL via Spring Data JPA. A API responde 201 Created com o id, a URL salva e o código.
A página junta o endereço do back-end com o código recebido, guarda o link completo num signal do Angular e mostra o resultado abaixo do campo. Quem abre esse link chama GET /urlshortener/{code}. O service busca o código pelo repository, e o controller responde 302 Found com um cabeçalho Location apontando para a URL original, ou 404 Not Found quando o código não existe.
O Hibernate cria ou atualiza a tabela na inicialização. A senha do banco vem de uma variável de ambiente, e as variáveis de ambiente padrão do Spring podem substituir a URL de conexão e o usuário. O controller libera requisições cross-origin do servidor de desenvolvimento local do Angular.
Tecnologias
- Front-end
- Angular 21, TypeScript 5.9, signals do Angular, HttpClient, Tailwind CSS 4
- Back-end
- Java 17, Spring Boot 4.1, Spring Web MVC, Spring Data JPA, Hibernate, MapStruct, Lombok, Apache Commons Text
- Dados
- PostgreSQL
- Ferramentas
- Maven, npm, Vitest, Prettier