"Um dos desafios mais clássicos, emblemáticos e traiçoeiros que sempre aparecem nas entrevistas pra programadora é se você sabe arquitetar um encurtador de URL, onde dado uma longa, você cria uma curta e toda vez que solicitada a URL curta, você redireciona o usuário paraa URL original." ~ Renato Augusto
- Encurtamento de URL: Dado um URL longo -> retornar um URL muito mais curto.
- Redirecionamento de URL: Dado um URL curto -> redirecionar para URL original.
- O sistema deve suportar 100 milhões de URLs geradas por dia.
- O tamanho da URL encurtada deve ser o mais curto possível.
- Somente números (0-9) e caracteres (a-z, A-Z) são permitidos na URL.
- Para cada 1 operação de gravação no banco de dados, haverão 10 operações de leitura.
- O comprimento médio das URLS armazenadas é de 100 bytes.
- URLs devem ser armazenadas pelo período mínio de 10 anos.
- O sistema deve operar em modo de alta disponibilidade (24/7)
- Node.js com TypeScript - Runtime e linguagem
- Fastify - Framework web de alta performance
- Redis - Cache em memória para armazenamento das URLs
- Apache Cassandra - Banco de dados NoSQL distribuído (3 nós)
- Hashids - Geração de IDs únicos curtos e seguros
- Zod - Validação de schemas
- Docker - Containerização dos serviços
O sistema utiliza a biblioteca Hashids para gerar códigos curtos únicos:
- Salt personalizado para segurança
- Alfabeto de 62 caracteres (0-9, a-z, A-Z)
- Comprimento mínimo de 7 caracteres
- Entrada baseada em:
url.length + url.charCodeAt(0) + Date.now()
- Redis como cache primário com TTL de 12 horas (dados quentes)
- Cassandra como fonte de verdade, com retenção de 10 anos
- Cluster Cassandra com 3 nós para alta disponibilidade
- Replicação automática dos dados
- Redis como cache distribuído
- Suporte para milhões de requisições por dia
// Endpoint de encurtamento da URL
*Request:
POST api/v1/shorten
BODY: {"url": "www.exemplo.com/..."}
*Response:
Status Code: 201 (created)
{"short_url": "bit.ly/zn9e10A"}
// Endpoint de redirecionamento da URL
*Request:
GET "bit.ly/zn9e10A"
*Response:
Status Code: 301/302 (redirect)
Header:
Location: "www.example.com/..."
- Node.js v22+
- Docker e Docker Compose
- pnpm
Crie um arquivo .env na raiz com, pelo menos:
HASHIDS_SALT=my_secret_key
REDIS_URL=redis://localhost:6379
- Clone o repositório:
git clone https://github.com/EaCamih/Encurtador
cd Encurtador- Instale as dependências:
pnpm install- Inicie os serviços (Redis e Cassandra):
docker-compose up -d- Execute a aplicação em modo de desenvolvimento:
pnpm devA API estará disponível em http://localhost:3333
pnpm dev- Inicia o servidor em modo de desenvolvimento com hot reloadpnpm build- Transpila o TypeScript para JavaScriptpnpm start- Inicia o servidor em modo de produçãopnpm format- Formata o código com Biome
Encurta uma URL longa
Request:
{
"url": "https://www.exemplo.com/artigo-muito-longo"
}Response (201 Created):
{
"short_url": "http://localhost:3333/cJ0xYz1"
}Redireciona para a URL original
Request:
GET http://localhost:3333/cJ0xYz1
Response:
302 Found- Redireciona para a URL original404 Not Found- URL não encontrada
A documentação interativa Swagger está disponível em:
http://localhost:3333/docs
- 100 milhões de URLs/dia × 365 dias × 10 anos = 365 bilhões de URLs
- Tamanho médio: 100 bytes por URL
- Total: ~36.5 TB de armazenamento
- Gravações: 100M URLs/dia ≈ 1,157 URLs/segundo
- Leituras: 10x gravações ≈ 11,570 URLs/segundo
- Alfabeto: 62 caracteres
- Comprimento: 7 caracteres
- Capacidade: 62^7 = 3.5 trilhões de combinações únicas
Este projeto está sob a licença MIT. Sinta-se à vontade para contribuir!
Desenvolvido pela Camilla Viana 💜
