Alternar tema

Como criar seu próprio encurtador de links com Workers + KV: do básico à prática

Easton editorial illustration: lifecycle journey rail

Eu usava um serviço de links curtos de terceiros havia quase dois anos. Certa manhã, descobri que todos os links tinham parado de funcionar: o provedor anunciou de repente que encerraria as atividades, e centenas de links compartilhados nas redes sociais passaram a retornar erro 404.

Naquele momento, pensei em criar um encurtador que fosse realmente meu. Assim, eu controlaria os dados, personalizaria o que quisesse e não dependeria mais da continuidade de um serviço de terceiros.

Foi então que percebi que Cloudflare Workers + armazenamento KV combinavam perfeitamente com essa necessidade:

  • Faixa gratuita muito ampla, com 100 mil solicitações por dia
  • Mais de 200 pontos de presença no mundo e acesso muito rápido
  • Implantação simples, com poucas linhas de código
  • Controle total dos dados e do período de armazenamento

Neste artigo, mostro como montei meu próprio encurtador com Workers + KV, incluindo códigos curtos personalizados e estatísticas de acesso. Todo o código está aqui; seguindo as etapas, é possível colocar o serviço no ar em cerca de meia hora.

Por que escolher Workers + KV?

O que é Cloudflare Workers?

Em termos simples, Workers permite executar funções Serverless na rede de borda da Cloudflare. Você escreve o código, ele é implantado automaticamente em mais de 200 pontos de presença, e cada acesso é direcionado ao ponto mais próximo do usuário, o que reduz muito a latência.

O principal destaque é a faixa gratuita generosa:

  • 100 mil solicitações por dia
  • 10 ms de CPU por solicitação
  • Em geral, suficiente para uso pessoal ou para uma pequena equipe

Vantagens do armazenamento KV

KV (Key-Value) é o banco de dados distribuído de chave e valor da Cloudflare, criado especialmente para computação de borda:

  • Leitura muito rápida: mediana de 12 ms, pois os dados ficam em cache nos pontos de presença
  • Sincronização global: uma gravação é propagada para todos os pontos em até 60 segundos
  • Faixa gratuita: 100 mil leituras e 1.000 gravações por dia

O KV combina naturalmente com serviços de links curtos:

  • O código curto funciona como key e a URL original como value
  • É um cenário com muitas leituras e poucas gravações: links são criados poucas vezes e acessados muitas
  • A distribuição global oferece acesso rápido em qualquer lugar
100 mil/dia
Faixa gratuita
100 mil solicitações por dia
12 ms
Velocidade de leitura do KV
Mediana, com dados em cache nos pontos de presença
200+
Pontos de presença globais
Acesso muito rápido
CaracterísticaServiço de terceirosWorkers + KV próprio
Controle dos dadosOs dados ficam com terceirosControle total
PersonalizaçãoRecursos fixosPersonalização livre
EstabilidadeO serviço pode encerrar as atividadesInfraestrutura da Cloudflare
AnúnciosPode haver uma página intermediáriaSem anúncios
CustoPode ser pagoPraticamente gratuito
VelocidadeDepende do provedorRede global de borda

Chega de teoria. Vamos à prática.

Preparação

1. Crie uma conta Cloudflare

Acesse cloudflare.com e crie uma conta. O plano gratuito é suficiente.

2. Instale a Wrangler CLI

Wrangler é a ferramenta oficial de linha de comando da Cloudflare para gerenciar projetos Workers.

npm install -g wrangler
# Ou use yarn
yarn global add wrangler

Depois da instalação, entre na sua conta Cloudflare:

wrangler login

O navegador será aberto para você autorizar o acesso. Basta clicar em permitir.

3. Crie o projeto

mkdir my-shortlink
cd my-shortlink
wrangler init

Siga as instruções e escolha criar um projeto JavaScript. Se preferir, também é possível usar TypeScript.

Etapa 1: crie o namespace KV

Antes de usar o armazenamento KV, é preciso criar um “namespace”. Pense nele como uma tabela de banco de dados.

Execute os comandos abaixo:

# Crie o namespace KV de produção
wrangler kv namespace create SHORTLINKS
# Crie o namespace KV de visualização, usado nos testes locais
wrangler kv namespace create SHORTLINKS --preview

Os comandos retornarão dois IDs, semelhantes a estes:

{ binding = "SHORTLINKS", id = "abc123..." }
{ binding = "SHORTLINKS", preview_id = "def456..." }

Importante: guarde os dois IDs; eles serão usados logo adiante.

Em seguida, edite o arquivo wrangler.toml e adicione o binding do KV:

name = "my-shortlink"
main = "src/index.js"
compatibility_date = "2025-12-01"
# Binding do namespace KV
kv_namespaces = [
  { binding = "SHORTLINKS", id = "seu ID de produção", preview_id = "seu ID de visualização" }
]

O trecho binding = "SHORTLINKS" indica que o KV poderá ser acessado no código por meio de env.SHORTLINKS.

Etapa 2: implemente as funções básicas do encurtador

Agora vamos escrever o código principal. Abra src/index.js e insira o conteúdo abaixo:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const path = url.pathname.slice(1); // 去掉开头的 /
    // 处理根路径
    if (path === '') {
      return new Response('欢迎使用短链服务!', { status: 200 });
    }
    // GET 请求:短链重定向
    if (request.method === 'GET') {
      // 从 KV 中查询短码对应的原始 URL
      const targetUrl = await env.SHORTLINKS.get(path);
      if (targetUrl) {
        // 找到了,301 重定向
        return Response.redirect(targetUrl, 301);
      } else {
        // 没找到,返回 404
        return new Response('短链不存在', { status: 404 });
      }
    }
    // POST 请求:创建短链
    if (request.method === 'POST') {
      try {
        const body = await request.json();
        const { url: targetUrl, code } = body;
        // 基本校验
        if (!targetUrl) {
          return new Response('缺少 url 参数', { status: 400 });
        }
        // 生成短码
        const shortCode = code || generateRandomCode();
        // 检查短码是否已存在
        const existing = await env.SHORTLINKS.get(shortCode);
        if (existing) {
          return new Response('短码已存在', { status: 409 });
        }
        // 存入 KV
        await env.SHORTLINKS.put(shortCode, targetUrl);
        // 返回结果
        return new Response(JSON.stringify({
          shortCode,
          shortUrl: `${url.origin}/${shortCode}`,
          targetUrl
        }), {
          status: 201,
          headers: { 'Content-Type': 'application/json' }
        });
      } catch (error) {
        return new Response('请求格式错误', { status: 400 });
      }
    }
    // 其他请求方法不支持
    return new Response('方法不允许', { status: 405 });
  }
};
// 生成随机短码(6位字母数字组合)
function generateRandomCode(length = 6) {
  const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  let code = '';
  for (let i = 0; i < length; i++) {
    code += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return code;
}

Como o código funciona:

  1. Solicitação GET: quando alguém acessa yourdomain.com/abc123, o Worker procura no KV a URL original associada a abc123 e faz um redirecionamento 301
  2. Solicitação POST: recebe os parâmetros url e code, este último opcional; se code não for informado, gera um valor aleatório e salva no KV
  3. generateRandomCode: gera uma combinação alfanumérica aleatória de 6 caracteres

Etapa 3: teste localmente

Depois de escrever o código, teste-o no ambiente local:

wrangler dev

Isso inicia um servidor local, normalmente em http://localhost:8787.

Teste a criação de um link curto:

curl -X POST http://localhost:8787 \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "code": "my-link"}'

Para tornar o serviço mais robusto, adicione algumas validações:

// 在 POST 请求处理部分,生成短码之前加上这段
// 如果用户提供了自定义短码,校验格式
if (code) {
  // 只允许字母、数字、连字符
  if (!/^[a-zA-Z0-9-]+$/.test(code)) {
    return new Response('短码格式不正确(仅支持字母、数字、连字符)', { status: 400 });
  }
  // 长度限制
  if (code.length < 3 || code.length > 20) {
    return new Response('短码长度必须在 3-20 之间', { status: 400 });
  }
}

Assim, ninguém poderá criar códigos estranhos, com caracteres especiais ou comprimento excessivo.

Etapa 5: implemente estatísticas de acesso

Em muitos casos, além de encurtar o link, também queremos saber quantas vezes ele foi acessado.

A ideia é a seguinte:

  • A cada acesso ao link curto, além do redirecionamento, aumente em 1 o contador de visitas
  • Armazene as estatísticas no KV com uma key no formato stats:{shortCode}

Altere o código que trata solicitações GET:

// GET 请求:短链重定向
if (request.method === 'GET') {
  const targetUrl = await env.SHORTLINKS.get(path);
  if (targetUrl) {
    // 异步更新访问统计(不阻塞重定向)
    const statsKey = `stats:${path}`;
    // 后台更新统计,不影响重定向速度
    env.SHORTLINKS.get(statsKey).then(count => {
      const newCount = (parseInt(count) || 0) + 1;
      env.SHORTLINKS.put(statsKey, newCount.toString());
    });
    return Response.redirect(targetUrl, 301);
  } else {
    return new Response('短链不存在', { status: 404 });
  }
}

Adicione uma rota para consultar as estatísticas:

// 在 GET 请求处理前,加上这个判断
if (path.startsWith('stats/')) {
  const shortCode = path.slice(6); // 去掉 stats/ 前缀
  const statsKey = `stats:${shortCode}`;
  const count = await env.SHORTLINKS.get(statsKey);
  return new Response(JSON.stringify({
    shortCode,
    visits: parseInt(count) || 0
  }), {
    headers: { 'Content-Type': 'application/json' }
  });
}

Agora você pode acessar http://localhost:8787/stats/abc123 para consultar a quantidade de visitas de um link curto.

Atenção: o KV não oferece operações atômicas, portanto as estatísticas podem não ser exatas em cenários de alta concorrência. Se você precisar de contagens precisas, use Durable Objects. Para a maioria dos projetos pessoais, porém, esta solução é suficiente.

Etapa 6: implante em produção

Depois que os testes estiverem funcionando, implante o projeto na rede global da Cloudflare:

wrangler deploy

Depois da implantação, a Wrangler fornecerá uma URL semelhante a https://my-shortlink.your-subdomain.workers.dev.

Esse é o endereço do seu encurtador, acessível globalmente e com alta velocidade.

Vincule um domínio personalizado (opcional):

Se você tiver seu próprio domínio, como short.example.com, poderá vinculá-lo pelo Cloudflare Dashboard:

  1. Acesse Workers & Pages
  2. Selecione o Worker
  3. Clique em Settings > Triggers
  4. Adicione um Custom Domain

Depois disso, você poderá acessar o encurtador pelo seu domínio, por exemplo: https://short.example.com/abc123.

Recursos avançados

As funções básicas estão prontas. Se quiser ir além, você pode adicionar os recursos a seguir.

Às vezes, é preciso criar vários links de uma só vez. Nesse caso, adicione uma rota para processamento em lote:

// 在 POST 请求处理部分,添加批量创建逻辑
if (request.method === 'POST' && url.pathname === '/batch') {
  try {
    const body = await request.json();
    const links = body.links; // 格式:[{url, code?}, ...]
    if (!Array.isArray(links)) {
      return new Response('links 必须是数组', { status: 400 });
    }
    const results = [];
    for (const link of links) {
      const { url: targetUrl, code } = link;
      const shortCode = code || generateRandomCode();
      // 检查是否已存在
      const existing = await env.SHORTLINKS.get(shortCode);
      if (!existing) {
        await env.SHORTLINKS.put(shortCode, targetUrl);
        results.push({ shortCode, targetUrl, success: true });
      } else {
        results.push({ shortCode, targetUrl, success: false, error: '短码已存在' });
      }
    }
    return new Response(JSON.stringify({ results }), {
      headers: { 'Content-Type': 'application/json' }
    });
  } catch (error) {
    return new Response('请求格式错误', { status: 400 });
  }
}

Exemplo de chamada:

curl -X POST http://localhost:8787/batch \
  -H "Content-Type: application/json" \
  -d '{
    "links": [
      {"url": "https://example1.com", "code": "link1"},
      {"url": "https://example2.com"}
    ]
  }'

2. Defina uma data de expiração

O KV aceita TTL (Time To Live), que permite fazer um link curto expirar automaticamente:

// 在存入 KV 时,添加 expirationTtl 参数
await env.SHORTLINKS.put(shortCode, targetUrl, {
  expirationTtl: 86400 // 24小时后自动删除,单位:秒
});

Para permitir que o usuário defina o prazo de expiração:

const { url: targetUrl, code, ttl } = body;
const options = {};
if (ttl) {
  options.expirationTtl = parseInt(ttl);
}
await env.SHORTLINKS.put(shortCode, targetUrl, options);

3. Controle de acesso

Se você não quiser permitir que qualquer pessoa crie links curtos, adicione uma autenticação simples por API Token:

// 在 wrangler.toml 里添加环境变量
# [vars]
# API_TOKEN = "your-secret-token"
// 在 POST 请求处理前,添加验证
if (request.method === 'POST') {
  const token = request.headers.get('Authorization');
  if (token !== `Bearer ${env.API_TOKEN}`) {
    return new Response('未授权', { status: 401 });
  }
  // ... 后续创建短链逻辑
}

Inclua o token na chamada:

curl -X POST http://localhost:8787 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secret-token" \
  -d '{"url": "https://example.com"}'

4. Evite abusos com Rate Limiting

Para impedir a criação maliciosa de muitos links, adicione um limite simples de frequência:

// 使用 IP 地址作为限流标识
const clientIp = request.headers.get('CF-Connecting-IP');
const rateLimitKey = `ratelimit:${clientIp}`;
// 获取当前计数
const count = await env.SHORTLINKS.get(rateLimitKey);
if (parseInt(count) >= 10) {
  return new Response('请求过于频繁,请稍后再试', { status: 429 });
}
// 计数 +1,设置 1 小时过期
const newCount = (parseInt(count) || 0) + 1;
await env.SHORTLINKS.put(rateLimitKey, newCount.toString(), {
  expirationTtl: 3600 // 1小时
});

Esse código limita cada endereço IP a no máximo 10 links novos por hora.

Otimização de desempenho e boas práticas

Dicas de otimização

1. Estratégia de cache

A leitura do KV já é rápida, com mediana de 12 ms, mas você pode adicionar uma camada de cache na memória do Worker:

// 使用 Map 作为简单的内存缓存
const cache = new Map();
const targetUrl = cache.get(path) || await env.SHORTLINKS.get(path);
if (targetUrl) {
  cache.set(path, targetUrl);
  return Response.redirect(targetUrl, 301);
}

Lembre-se de que a memória do Worker não é persistente e será perdida quando ele reiniciar.

2. Reduza a quantidade de gravações no KV

A faixa gratuita do KV inclui 1.000 gravações por dia. Se as estatísticas forem atualizadas em todos os acessos, esse limite poderá ser ultrapassado.

Há algumas alternativas:

  • Use Durable Objects para processar as estatísticas, pois eles aceitam operações atômicas
  • Grave no KV apenas a cada N acessos
  • Use Cloudflare Analytics Engine

3. Configuração de CORS

Se um frontend precisar chamar o serviço, não se esqueça de adicionar os cabeçalhos CORS:

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type',
};
// OPTIONS 请求处理
if (request.method === 'OPTIONS') {
  return new Response(null, { headers: corsHeaders });
}
// 在返回响应时添加 CORS 头
return new Response(body, {
  headers: { ...headers, ...corsHeaders }
});

Controle de custos

A faixa gratuita do Cloudflare Workers é muito generosa, mas ainda exige atenção:

Faixa gratuita:

  • 100 mil solicitações por dia
  • 100 mil leituras e 1.000 gravações de KV por dia
  • 10 ms de CPU por solicitação

Custos acima da faixa gratuita, no plano Workers Paid a partir de US$ 5 por mês:

  • US$ 0,50 por milhão de solicitações
  • US$ 0,50 por milhão de leituras de KV
  • US$ 5,00 por milhão de gravações de KV
  • US$ 0,50 por GB de armazenamento de KV por mês

Para uso pessoal, dificilmente você ultrapassará a faixa gratuita. Mesmo uma pequena equipe com dezenas de milhares de acessos por dia provavelmente ficará dentro dela.

Dicas para economizar solicitações:

  • Use redirecionamento 301, armazenado em cache pelo navegador, em vez de 302
  • Hospede recursos estáticos, como o painel, no Workers Pages para não consumir solicitações do Worker
  • Configure o TTL adequadamente para remover links expirados

Cuidados de segurança

1. Evite links maliciosos

Se o encurtador estiver aberto ao público, alguém poderá usá-lo para encurtar links de sites maliciosos.

Recomendações:

  • Adicione autenticação por API Token
  • Use uma lista de bloqueio para filtrar domínios maliciosos conhecidos
  • Registre o IP de quem criou o link para facilitar o rastreamento

2. Evite colisões de código

Embora uma combinação alfanumérica de 6 caracteres ofereça 62^6 ≈ 56,8 bilhões de possibilidades e a chance de colisão seja muito baixa, ainda é preciso verificar se o código já existe:

// 创建短链时,检查是否已存在
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
  return new Response('短码已存在', { status: 409 });
}

3. Restrinja a URL de destino

Você pode criar uma lista de permissões para aceitar redirecionamentos apenas a domínios específicos:

const allowedDomains = ['example.com', 'mywebsite.com'];
const targetDomain = new URL(targetUrl).hostname;
if (!allowedDomains.some(d => targetDomain.endsWith(d))) {
  return new Response('不允许的目标域名', { status: 403 });
}

Minha experiência de uso na prática

Depois de montar o serviço, eu o usei por vários meses. Estas foram minhas impressões.

Pontos positivos:

  • É realmente rápido: a latência global geralmente fica abaixo de 50 ms, muito melhor do que no serviço de terceiros que eu usava
  • É estável: a rede da Cloudflare é muito estável e praticamente não tive indisponibilidade
  • Dá pouco trabalho: depois da implantação, o serviço escala automaticamente e não exige preocupação com picos de tráfego
  • É gratuito: recebo alguns milhares de solicitações por dia, todas dentro da faixa gratuita

Limitações:

  • A gravação no KV tem atraso: como o KV oferece consistência eventual, a sincronização global pode levar dezenas de segundos. Isso afeta pouco os links curtos, pois normalmente ninguém os acessa imediatamente depois da criação
  • As estatísticas não são exatas: o KV não oferece operações atômicas, então pode haver diferenças em cenários de alta concorrência. Para estatísticas precisas, é necessário usar Durable Objects, cujo custo acima da faixa gratuita é um pouco maior

Próximos passos:

  • Criar um Dashboard simples com Workers Pages para administrar visualmente os links
  • Integrar o Cloudflare Analytics para consultar origem, região e outros dados detalhados de acesso
  • Adicionar geração de QR codes para facilitar o compartilhamento offline

Conclusão

Criar um encurtador com Cloudflare Workers + KV é rápido e econômico. O código principal tem menos de 100 linhas, a implantação exige um único comando e, acima de tudo, os dados ficam totalmente sob seu controle, sem o risco de depender da continuidade de um serviço de terceiros.

Se você tem uma necessidade parecida, vale a pena experimentar. Todo o código está neste artigo; seguindo as etapas, é possível colocar o serviço no ar em cerca de meia hora.

Resumo das etapas principais:

  1. Crie uma conta Cloudflare e instale a Wrangler CLI
  2. Crie o namespace KV e configure o wrangler.toml
  3. Escreva o código para tratar solicitações GET, que redirecionam, e POST, que criam links curtos
  4. Teste localmente e implante em produção

Depois, você pode adicionar aos poucos recursos como estatísticas, criação em lote e data de expiração. Como o código é seu, você tem liberdade total para adaptá-lo.

Se tiver alguma dúvida, deixe um comentário. Espero que você também consiga criar seu próprio encurtador de links!
-H “Content-Type: application/json”
-d ’{“url”: “https://example.com”}


A resposta será semelhante a esta:

```json
{
  "shortCode": "aBc123",
  "shortUrl": "http://localhost:8787/aBc123",
  "targetUrl": "https://example.com"
}

Teste o acesso ao link curto:

Abra http://localhost:8787/aBc123 no navegador. Você deverá ser redirecionado para https://example.com.

Se tudo funcionar, a implementação básica está pronta.

Etapa 4: adicione códigos curtos personalizados

O código acima já aceita um código personalizado. Basta incluir o parâmetro code na solicitação POST:

curl -X POST http://localhost:8787 \

Processo completo para criar um encurtador de links com Cloudflare Workers + KV

Crie do zero um serviço com geração de links curtos, redirecionamento e estatísticas de acesso, pronto em cerca de meia hora

⏱️ Estimated time: 30 min

  1. 1

    Step 1: Preparação: criar uma conta Cloudflare e instalar a Wrangler CLI

    Primeiro passo: crie uma conta Cloudflare
    • Acesse cloudflare.com e crie uma conta; o plano gratuito é suficiente

    Segundo passo: instale a Wrangler CLI
    • Wrangler é a ferramenta oficial de linha de comando da Cloudflare para gerenciar projetos Workers
    • Execute: npm install -g wrangler
    • Ou use: yarn global add wrangler
    • Depois da instalação, entre na sua conta Cloudflare: wrangler login
    • O navegador será aberto para você autorizar o acesso; basta clicar em permitir

    Terceiro passo: crie o projeto
    • mkdir my-shortlink
    • cd my-shortlink
    • wrangler init
    • Siga as instruções e escolha criar um projeto JavaScript, embora também seja possível usar TypeScript
  2. 2

    Step 2: Criar um namespace KV e configurar o wrangler.toml

    Crie um namespace KV:

    Opção 1: pelo Cloudflare Dashboard
    • Acesse Workers & Pages → KV
    • Clique em Create a namespace
    • Informe um nome, como SHORTLINKS, e crie o namespace

    Opção 2: pela linha de comando
    • wrangler kv:namespace create SHORTLINKS

    Configure o wrangler.toml:
    Abra o arquivo wrangler.toml e adicione ao final a configuração do binding KV:

    [[kv_namespaces]]
    binding = "SHORTLINKS"
    id = "ID do seu namespace"

    Assim, o KV poderá ser acessado no código por meio de env.SHORTLINKS
  3. 3

    Step 3: Escrever o código principal: criação e redirecionamento de links curtos

    Implemente as funções principais:

    1. Gere o código curto:
    • Aceite um código personalizado ou gere um aleatoriamente
    • É possível usar uma combinação alfanumérica de 6 caracteres
    • Existem 62^6 ≈ 56,8 bilhões de combinações, portanto a chance de colisão é muito baixa

    2. Armazene no KV:
    • Use o código curto como key e a URL original como value
    • Também é possível armazenar metadata, como data de criação e quantidade de acessos

    3. Faça o redirecionamento:
    • Em uma solicitação GET, leia a URL original no KV
    • Retorne um redirecionamento 302 para a URL original

    4. Registre estatísticas de acesso:
    • Registre a quantidade e o horário dos acessos
    • Esses dados podem ser armazenados na metadata do KV

    Exemplos de código:
    • Tratamento de GET, para redirecionar: obtenha o código curto do caminho da URL, leia a URL original no KV e retorne um redirecionamento 302 se ela existir ou um erro 404 caso contrário
    • Tratamento de POST, para criar o link curto: receba a URL original e um código personalizado opcional, gere o código, verifique se ele já existe para evitar colisões, salve no KV e retorne a URL curta
  4. 4

    Step 4: Testar localmente e implantar em produção

    Teste local:

    1. Execute wrangler dev para iniciar o servidor de desenvolvimento local
    2. Teste a criação e o redirecionamento de links curtos

    Você pode testar com curl:
    • Criar um link curto:
    curl -X POST http://localhost:8787/create -H "Content-Type: application/json" -d '{"url":"https://example.com"}'

    • Acessar o link curto:
    curl -L http://localhost:8787/abc123
    (o acesso será redirecionado para a URL original)

    Implante em produção:
    • Execute: wrangler deploy
    • A Wrangler implantará automaticamente o Worker na Cloudflare
    • Depois da implantação, você verá uma URL com este formato:
    your-worker-name.your-subdomain.workers.dev
    • Seu encurtador de links estará no ar
  5. 5

    Step 5: Recursos avançados e cuidados de segurança

    Recursos avançados: 1) estatísticas de acesso, registrando quantidade e horário dos acessos na metadata do KV e atualizando o contador a cada visita; 2) data de expiração, para invalidar automaticamente um link curto; 3) criação em lote, para gerar vários links de uma só vez; 4) painel de gerenciamento, usando Workers Pages para criar um Dashboard simples e administrar visualmente os links. Cuidados de segurança: 1) evite links maliciosos com autenticação por API Token, uma lista de bloqueio de domínios maliciosos conhecidos e registro do IP de quem criou o link; 2) evite colisões de código, pois, embora 6 caracteres alfanuméricos ofereçam 62^6 ≈ 56,8 bilhões de combinações e a chance seja baixa, ainda é necessário verificar se o código já existe; 3) restrinja a URL de destino com uma lista de permissões para domínios específicos. Para economizar solicitações, use redirecionamento 301, que o navegador armazena em cache, em vez de 302; hospede recursos estáticos, como o painel, no Workers Pages para não consumir solicitações do Worker; e configure o TTL adequadamente para remover links expirados.

FAQ

Por que criar um encurtador de links próprio? Quais são as vantagens de Workers + KV?
Se um serviço de terceiros encerrar as atividades de repente, centenas de links podem deixar de funcionar. Com um encurtador próprio, os dados ficam totalmente sob seu controle, os recursos podem ser personalizados e você não precisa se preocupar com o desaparecimento do fornecedor.

Vantagens de Workers + KV:
• Ampla faixa gratuita, com 100 mil solicitações por dia
• Mais de 200 pontos de presença no mundo para acesso rápido
• Implantação simples, com poucas linhas de código
• Controle total dos dados e do período de armazenamento

Comparação com serviços de terceiros:
• Controle dos dados: ficam com o fornecedor no serviço de terceiros e sob seu controle na solução própria
• Personalização: recursos fixos no serviço de terceiros e livre adaptação na solução própria
• Estabilidade: o serviço de terceiros pode encerrar as atividades; a solução própria usa a infraestrutura da Cloudflare
• Anúncios: terceiros podem exibir uma página intermediária; a solução própria não tem anúncios
• Custo: terceiros podem cobrar; a solução própria é praticamente gratuita
• Velocidade: em terceiros, depende do provedor; na solução própria, usa a rede global de borda
Quais são as vantagens do armazenamento KV e por que ele é adequado para links curtos?
KV (Key-Value) é o banco de dados distribuído de chave e valor da Cloudflare, otimizado para computação de borda.

Vantagens do KV:
• Leitura muito rápida, com mediana de 12 ms, pois os dados ficam em cache nos pontos de presença
• Sincronização global em até 60 segundos depois de uma gravação
• Faixa gratuita de 100 mil leituras e 1.000 gravações por dia

O KV combina muito bem com um serviço de links curtos:
• O código curto funciona como key e a URL original como value
• O cenário tem muitas leituras e poucas gravações, pois os links são criados poucas vezes e acessados muitas
• A distribuição global oferece acesso rápido em qualquer lugar

Faixa gratuita:
• 100 mil solicitações de Workers por dia
• 100 mil leituras e 1.000 gravações de KV por dia
• Em geral, isso é suficiente para uso pessoal e até para pequenas equipes com dezenas de milhares de acessos diários

Custos acima da faixa gratuita, no plano Workers Paid a partir de US$ 5 por mês:
• US$ 0,50 por milhão de solicitações
• US$ 0,50 por milhão de leituras de KV
• US$ 5,00 por milhão de gravações de KV
• US$ 0,50 por GB de armazenamento de KV por mês
Como criar um encurtador de links do zero? Quais são as etapas?
Preparação:

Primeiro passo: crie uma conta Cloudflare em cloudflare.com; o plano gratuito é suficiente
Segundo passo: instale a Wrangler CLI com npm install -g wrangler e depois faça login com wrangler login
Terceiro passo: crie o projeto com mkdir my-shortlink, cd my-shortlink e wrangler init

Crie e configure o namespace KV:
• No Cloudflare Dashboard, acesse Workers & Pages → KV, clique em Create a namespace, informe um nome, como SHORTLINKS, e crie o namespace
• Ou execute na linha de comando: wrangler kv:namespace create SHORTLINKS

Configure o wrangler.toml:
• Abra o arquivo wrangler.toml e adicione ao final a configuração do binding KV
• Assim, o KV poderá ser acessado no código por meio de env.SHORTLINKS

Escreva o código principal:

Tratamento de GET, para redirecionar:
• Obtenha o código curto no caminho da URL
• Leia a URL original no KV
• Se ela existir, retorne um redirecionamento 302; caso contrário, retorne 404

Tratamento de POST, para criar o link curto:
• Receba a URL original e um código personalizado opcional
• Gere um código aleatório se o usuário não informar um
• Verifique se o código já existe para evitar colisões
• Salve no KV e retorne a URL curta

Teste localmente e implante:
• Execute wrangler dev para iniciar o servidor local e testar a criação e o redirecionamento
• Execute wrangler deploy para implantar em produção
Como implementar as principais funções do encurtador de links?
Implemente as funções principais:

1) Gere o código curto:
• Aceite um código personalizado ou gere um aleatoriamente
• Uma combinação alfanumérica de 6 caracteres oferece 62^6 ≈ 56,8 bilhões de possibilidades, com chance muito baixa de colisão

2) Armazene no KV:
• Use o código curto como key e a URL original como value
• Também é possível armazenar metadata, como data de criação e quantidade de acessos

3) Faça o redirecionamento:
• Em uma solicitação GET, leia a URL original no KV
• Retorne um redirecionamento 302 para a URL original

4) Registre estatísticas de acesso:
• Registre a quantidade e o horário dos acessos
• Os dados podem ser armazenados na metadata do KV e o contador atualizado a cada acesso

Exemplos de código:

Tratamento de GET, para redirecionar:
• Obtenha o código curto no caminho da URL
• Leia a URL original no KV
• Se ela existir, retorne um redirecionamento 302; caso contrário, retorne 404

Tratamento de POST, para criar o link curto:
• Receba a URL original e um código personalizado opcional
• Gere um código aleatório se o usuário não informar um
• Verifique se o código já existe para evitar colisões
• Salve no KV, usando o código curto como key e a URL original como value
• Retorne a URL curta

Recursos avançados:
• Estatísticas de acesso, com quantidade e horário das visitas
• Data de expiração, para invalidar automaticamente o link
• Criação em lote de vários links
• Painel feito com Workers Pages para administrar visualmente os links
Quais cuidados de segurança um encurtador de links exige?
Cuidados de segurança:

1) Evite links maliciosos:
• Se o serviço estiver aberto ao público, alguém poderá usá-lo para encurtar links de sites maliciosos
• Recomendações:
- Adicione autenticação por API Token
- Use uma lista de bloqueio para filtrar domínios maliciosos conhecidos
- Registre o IP de quem criou o link para facilitar o rastreamento

2) Evite colisões de código:
• Embora 6 caracteres alfanuméricos ofereçam 62^6 ≈ 56,8 bilhões de possibilidades e a chance de colisão seja baixa, ainda é preciso verificar
• Ao criar o link, confira se o código já existe:
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
return new Response('O código curto já existe', { status: 409 });
}

3) Restrinja a URL de destino:
• Use uma lista de permissões para redirecionar apenas a domínios específicos:
const allowedDomains = ['example.com', 'mywebsite.com'];
const targetDomain = new URL(targetUrl).hostname;
if (!allowedDomains.some(d => targetDomain.endsWith(d))) {
return new Response('Domínio de destino não permitido', { status: 403 });
}

Dicas para economizar solicitações:
• Use redirecionamento 301, armazenado em cache pelo navegador, em vez de 302
• Hospede recursos estáticos, como o painel, no Workers Pages para não consumir solicitações do Worker
• Configure o TTL adequadamente para remover links expirados
Como é a experiência de uso na prática? Quais são os pontos positivos e negativos?
Experiência de uso na prática:

Pontos positivos:
• É realmente rápido: a latência global geralmente fica abaixo de 50 ms, muito melhor do que no serviço de terceiros usado antes
• É estável: a rede da Cloudflare é muito estável e praticamente não houve indisponibilidade
• Dá pouco trabalho: depois da implantação, há escalabilidade automática e não é preciso se preocupar com picos de tráfego
• É gratuito: alguns milhares de solicitações por dia ficam completamente dentro da faixa gratuita

Limitações:
• A gravação no KV tem atraso: como o KV oferece consistência eventual, a sincronização global pode levar dezenas de segundos; isso afeta pouco os links curtos, pois normalmente ninguém os acessa imediatamente depois da criação
• As estatísticas não são exatas: o KV não oferece operações atômicas, então pode haver diferenças em cenários de alta concorrência; para estatísticas exatas, use Durable Objects, embora o custo acima da faixa gratuita seja maior

Próximos passos:
• Criar um Dashboard simples com Workers Pages para administrar visualmente os links
• Integrar o Cloudflare Analytics para consultar origem, região e outros dados detalhados de acesso
• Adicionar geração de QR codes para facilitar o compartilhamento offline

14 min de leitura · Publicado em: 1 dez 2025 · Atualizado em: 4 set 2026

Comentários

Entre com GitHub para comentar

Easton BlogEaston Blog