“`html
Edge Computing
Edge Computing com Cloudflare Workers
Aprenda como estruturar requisições, reduzir latência e aplicar lógica de negócio na borda do Cloudflare
usando Workers. Um guia técnico e direto ao ponto para você colocar o “tráfego perto do usuário” no ar.
1) O que muda com Workers na borda
Quando eu falo de edge-computing, a ideia central é simples: executar código mais perto do
usuário (ou do ponto de rede mais “perto” possível) para diminuir tempo de resposta, reduzir saltos e,
principalmente, controlar o comportamento HTTP antes de chegar em suas aplicações de origem.
Com Cloudflare Workers, você recebe eventos HTTP e executa lógica em JavaScript/TypeScript
com acesso a APIs do ecossistema Cloudflare. Na prática, você ganha uma camada programável para:
- Roteamento e transformação de requisições (ex.: mudar headers, escolher backends);
- Cache inteligente para reduzir carga e custos;
- Autenticação e autorização de forma centralizada;
- Observabilidade (logs/telemetria) e respostas consistentes;
- Integrações leves (ex.: validações, webhooks, edge APIs).
Dica prática: pense em Workers como um “front de lógica” — você não precisa reescrever seu sistema.
Você só injeta as decisões onde elas fazem mais sentido: na borda.
2) Fluxo técnico: request, fetch e resposta
No Workers, o fluxo típico envolve capturar a requisição (evento), aplicar regras e, quando necessário,
fazer um fetch para a origem. O que define a arquitetura é como você decide:
- Quando responder diretamente (ex.: endpoints de saúde, respostas mockadas, regras simples);
- Quando encaminhar para o backend;
- Como tratar timeouts e erros (fallbacks e códigos HTTP coerentes);
- Quais headers preservar ou sobrescrever (para não “quebrar” cache ou autenticação);
- Quais caminhos usar para cache e invalidar com precisão.
Em termos de comportamento HTTP, eu costumo seguir três pilares:
- Idempotência onde importa: cache e GET devem ser previsíveis; POST/PUT exigem cuidado.
- Consistência de Vary: se a resposta depende de headers (idioma, token, etc.), defina
variáveis de cache corretamente para evitar servir conteúdo indevido. - Separação de responsabilidades: validação/roteamento no edge; lógica pesada no origin.
3) Estratégias de cache e redução de latência
O ganho real do edge costuma aparecer quando você desenha cache com intenção. Com Workers, você pode:
responder via cache, consultar cache antes de buscar na origem e controlar o tempo de vida com granularidade.
As estratégias que mais vejo funcionando bem:
-
Cache-first para conteúdo estático/sem estado:
imagens, scripts e respostas previsíveis. -
Stale-while-revalidate (quando aplicável):
devolve a última versão e atualiza em segundo plano, reduzindo picos. -
TTL por rota e por “perfil” de resposta:
respostas “quase constantes” podem ter TTL maior do que respostas sensíveis. -
Cache baseado em chave correta:
inclua os fatores que mudam a resposta (querystring, idioma, etc.) para evitar inconsistência.
Importante: cache não é “habilitar e esquecer”. É engenharia de consistência. Se a resposta depende
de autenticação ou dados por usuário, trate isso com cuidado (ou não cacheie).
4) Segurança e observabilidade na borda
Workers também é um excelente ponto para “endurecer” a borda: validações antes do tráfego chegar no origin,
uniformizar erros e reduzir superfície de ataque.
Segurança que eu priorizo:
-
Validação de entrada:
normalize parâmetros, valide formatos e recuse payloads inesperados com códigos adequados. -
Controle de headers:
remove headers perigosos e defina os que seu origin espera. -
Proteção de endpoints:
aplique autenticação/autorização no edge quando a decisão pode ser tomada cedo. -
Rate limiting (quando aplicável no seu contexto):
bloqueie abusos antes de sobrecarregar a origem.
Observabilidade:
- Logs com contexto (método, rota, status, tempo de execução) para diagnosticar rapidamente.
- Respostas de erro padronizadas para facilitar debug e monitoramento.
- Métricas por rota para enxergar gargalos e ajustar cache/roteamento.
Exemplo: endpoint com roteamento, headers e cache controlado
Abaixo eu deixo um exemplo com lógica de borda: serve uma resposta curta e, para rotas “dinâmicas”,
encaminha para o origin ajustando headers e usando cache conforme o método e a presença de querystring.
TypeScript / JavaScript (Fetch Handler)
// src/index.ts
export default {
async fetch(request: Request, env: any, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
const method = request.method.toUpperCase();
const pathname = url.pathname;
// Exemplo de endpoint local (responde direto no edge)
if (method === "GET" && pathname === "/health") {
return new Response(JSON.stringify({ ok: true, at: Date.now() }), {
status: 200,
headers: {
"content-type": "application/json; charset=utf-8",
"cache-control": "no-store"
}
});
}
// Exemplo: somente GET cacheável (evita cachear POST/PUT)
const isGet = method === "GET";
const hasQuery = url.search.length > 0;
const cacheable = isGet && !hasQuery;
// Ajuste de headers antes do origin (preserva o que faz sentido)
const reqHeaders = new Headers(request.headers);
reqHeaders.set("x-request-path", pathname);
// Exemplo simples de controle: se você tem regras específicas, aplique aqui
// (evite propagar headers que não fazem sentido pro origin)
reqHeaders.delete("x-forwarded-host"); // exemplo (ajuste para seu cenário)
const originUrl = new URL(env.ORIGIN_BASE); // ex.: "https://api.suaempresa.com"
originUrl.pathname = pathname;
originUrl.search = url.search; // mantém query para rotas que precisam dela
const originRequest = new Request(originUrl.toString(), {
method,
headers: reqHeaders,
body: request.body,
redirect: "manual"
});
// Cache controlado: responde do cache quando permitido
// (conceitualmente: chave baseada no URL completo; a política decide o TTL)
const cache = caches.default;
if (cacheable) {
const cacheKey = new Request(originUrl.toString(), { method: "GET" });
const cached = await cache.match(cacheKey);
if (cached) return withCorsAndSecurity(cached);
}
try {
const start = Date.now();
const response = await fetch(originRequest);
// Se for sucesso, você pode armazenar no cache conforme sua regra
if (cacheable && response.ok) {
// Clone para permitir leitura do body e cache
const responseClone = response.clone();
// Define TTL via header (padrão do seu fluxo)
responseClone.headers.set("cache-control", "public, max-age=60");
const cacheKey = new Request(originUrl.toString(), { method: "GET" });
ctx.waitUntil(cache.put(cacheKey, responseClone));
}
// Encapsula e garante headers consistentes
const enriched = withCorsAndSecurity(response);
enriched.headers.set("x-edge-duration-ms", String(Date.now() - start));
return enriched;
} catch (err: any) {
return new Response(JSON.stringify({
error: "edge_upstream_failed",
message: "Falha ao consultar a origem.",
details: String(err?.message || err)
}), {
status: 502,
headers: {
"content-type": "application/json; charset=utf-8",
"cache-control": "no-store"
}
});
}
}
};
function withCorsAndSecurity(response: Response): Response {
// Repare: você pode padronizar CORS e segurança aqui
const headers = new Headers(response.headers);
headers.set("x-content-type-options", "nosniff");
headers.set("x-frame-options", "DENY");
// Exemplo de CORS (ajuste para seu domínio)
headers.set("access-control-allow-origin", "*");
headers.set("access-control-allow-methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers
});
}
Observação: nesse exemplo eu cacheio apenas GET sem querystring para manter a consistência.
No mundo real, eu ajustaria a chave e a política conforme a dependência de headers/queries.
Quer aprofundar em práticas de arquitetura e HTTP?
Se você curtiu o caminho “edge como camada de decisão”, recomendo continuar por outros posts técnicos do
yurideveloper.com. Eles ajudam a fechar o ciclo: pensar em cache, consistência, segurança e
modelagem de endpoints.
Se quiser, eu também posso adaptar esse exemplo para o seu cenário (rotas, requisitos de cache, autenticação e origem).
“`
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!