Sobre · Funcionalidades · Stack · Como funciona · Arquitetura · Rodando localmente · Testes · Deploy · API · Decisões técnicas · Melhorias futuras · Autor
Linkael transforma URLs longas em links curtos e memoráveis, com uma arquitetura 100% serverless que roda direto na borda da rede Cloudflare — sem servidor para gerenciar e com resposta praticamente instantânea.
O projeto nasceu como exercício de Cloud Computing e evoluiu para um encurtador completo: gera links com código automático ou personalizado, controla acessos com rate limiting, mede o desempenho de cada link com um contador de cliques, e ainda gera um QR code automático para cada link criado.
|
🔗 Encurtamento inteligente
Aceita URLs com |
🎲 Código automático Geração automática de código curto com 6 caracteres alfanuméricos. |
✏️ Código personalizado
Suporte a slugs customizados, como |
|
📊 Contador de cliques Cada link acompanha quantas vezes foi acessado, disponível via API de estatísticas. |
🧾 QR code automático Ao gerar um link, um QR code é exibido na hora para compartilhamento offline. |
🛡️ Rate limiting Limite de requisições por IP no endpoint de criação, prevenindo abuso. |
|
✅ Validação completa Verificação de formato de URL e do código personalizado informado. |
🚫 Códigos reservados Bloqueio de códigos que conflitariam com rotas internas da aplicação. |
🔍 Anti-duplicidade Checagem de código já existente antes de salvar no KV. |
|
↪️ Redirecionamento 302 Redirecionamento automático para a URL original ao acessar o link curto. |
🧪 Testes automatizados Cobertura de validações com Vitest, rodando no CI a cada push. |
⚙️ CI/CD Deploy automático via GitHub Actions após os testes passarem. |
| Tecnologia | Papel no projeto |
|---|---|
| Cloudflare Workers | Executa o backend serverless e roteia as requisições |
| Cloudflare KV | Armazena código, URL original, cliques e data de criação |
| Wrangler | Ferramenta de desenvolvimento e deploy da Cloudflare |
| Vitest | Testes unitários das regras de validação |
| GitHub Actions | Pipeline de testes e deploy automático |
| HTML, CSS e JavaScript | Interface web sem dependências de framework |
flowchart LR
A["📝 Usuário informa a URL"] --> B["📤 Frontend envia POST /api/shorten"]
B --> C["🛡️ Worker valida e checa rate limit"]
C --> D["💾 Worker salva código → URL no KV"]
D --> E["✅ API retorna link curto + QR code"]
F["🌐 Usuário acessa /código"] --> G["🔍 Worker consulta o KV"]
G --> H["📈 Incrementa contador de cliques"]
H --> I["↪️ Redirecionamento 302"]
classDef primary fill:#0F6E56,stroke:#0F6E56,stroke-width:1px,color:#F1F5F9
classDef secondary fill:#173404,stroke:#173404,stroke-width:1px,color:#F1F5F9
classDef neutral fill:#444441,stroke:#444441,stroke-width:1px,color:#F1F5F9
class A,F primary
class B,C,G,H secondary
class D,E,I neutral
- O usuário cola a URL original e, opcionalmente, informa um código personalizado.
- O frontend envia os dados para
/api/shorten. - O Worker checa o rate limit, valida a URL e o código, evitando conflitos com códigos já existentes.
- O Cloudflare KV salva o registro
{ url, clicks, createdAt }na chave do código. - A aplicação retorna o link curto e exibe um QR code gerado na hora.
- Ao acessar o link curto, o Worker busca o destino no KV, incrementa o contador de cliques e redireciona automaticamente.
O projeto roda sem servidor tradicional. O frontend é servido como asset estático e o backend fica concentrado em um Worker, com as regras de validação isoladas em um módulo separado para facilitar os testes.
linkael/
├── public/
│ ├── index.html
│ ├── style.css
│ └── script.js
├── src/
│ └── validators.js
├── test/
│ └── validators.test.js
├── .github/
│ └── workflows/
│ └── deploy.yml
├── worker.js
├── wrangler.toml
├── package.json
├── API.md
└── README.md
- 📨
worker.jsrecebe requisições de encurtamento emPOST /api/shorten, serve os arquivos estáticos e redireciona os códigos curtos. - 🧩
src/validators.jsconcentra as regras de validação, testadas isoladamente emtest/validators.test.js. - ⚙️
.github/workflows/deploy.ymlroda os testes a cada push/PR e faz o deploy automático quando a branchmainé atualizada.
Pré-requisitos: Node.js instalado · conta na Cloudflare · Wrangler instalado (ou executado via
npx)
git clone https://github.com/raelmz/linkael.git
cd linkael
npm install
wrangler login
wrangler devPor padrão, o Wrangler inicia o projeto em:
http://127.0.0.1:8787
Para criar um namespace KV na Cloudflare:
wrangler kv namespace create LINKSDepois, copie o id gerado para o binding LINKS no arquivo wrangler.toml.
npm testOs testes cobrem as regras de validação de URL, código personalizado e códigos reservados. O mesmo comando roda automaticamente no GitHub Actions a cada push ou pull request.
wrangler deployO deploy publica o Worker, disponibiliza os arquivos estáticos e conecta a aplicação ao namespace KV configurado na conta Cloudflare.
Para deploy automático via GitHub Actions, adicione o secret CLOUDFLARE_API_TOKEN nas configurações do repositório (Settings → Secrets and variables → Actions). O token pode ser gerado em Cloudflare Dashboard → My Profile → API Tokens, usando o template "Edit Cloudflare Workers".
Documentação completa dos endpoints em API.md.
- Cloudflare KV — escolhido porque o caso de uso principal é uma consulta chave-valor simples, ideal para mapear
código -> registro. - Registro em JSON no KV — em vez de salvar só a URL, o valor armazenado é um objeto
{ url, clicks, createdAt }, permitindo estatísticas sem precisar de outro banco. - Rate limiting no próprio KV — evita a necessidade de um serviço externo só para limitar requisições, usando
expirationTtlpara expirar a janela automaticamente. - Validações isoladas em
src/validators.js— separar regras de negócio da camada de rede facilita testes unitários sem precisar simular o runtime completo do Worker. - Redirecionamento 302 — evita cache permanente do destino pelo navegador.
- Códigos reservados — impedem conflito entre links personalizados e rotas internas como
/apie/stats.
- Expiração automática de links (TTL configurável)
- Painel autenticado para gerenciar links
- Preview Open Graph ao compartilhar o link curto
- Analytics por país de origem do clique
- Domínio próprio conectado ao Worker