Edge Computing com Claude Code: Workers, cache e rotas por região
Projete Edge runtime com Claude Code: Workers, região, cache keys, riscos e comandos de verificação.
Edge computing é tomar pequenas decisões perto do usuário. Não significa mover todo o backend para a borda da rede. Significa resolver redirecionamentos, cache curto, distribuição de A/B test ou bloqueios simples antes que a requisição chegue à aplicação principal.
Por isso, Edge runtime não é um botão mágico de performance. Ele não é um servidor Node.js comum. APIs disponíveis, tempo de execução, pacotes, metadados da requisição e comportamento de cache têm limites. Se você pedir ao Claude Code apenas “deixe isso pronto para edge”, ele pode importar APIs exclusivas de Node, montar uma cache key errada ou usar país como prova de cobrança e permissão.
Este guia usa documentação oficial verificada em 2 de junho de 2026. Mantenha abertos Cloudflare Workers, Workers Request API, Workers Cache API, Vercel Edge Runtime, Deno Deploy runtime e Claude Code overview. Para aprofundar por plataforma, veja também Cloudflare Workers com Claude Code e Vercel Edge Functions com Claude Code.
Decida o que pertence ao Edge
O primeiro passo é separar controle de entrada de lógica de negócio. Se a decisão pode ser tomada com URL, headers, cookies ou um corpo pequeno, ela pode caber no Edge. Se exige leituras profundas de banco, chamadas longas a LLM, processamento de imagem, PDF, fechamento de pagamento ou tarefa em background, deixe em uma API comum ou fila.
| Caso de uso | Por que combina com Edge | Deixe fora do Edge |
|---|---|---|
| Rota por país ou idioma | Código de país ou header de idioma escolhe a entrada rápido | Impostos, faturas, estoque |
| Cache curto | Resposta pública pode ser servida perto do usuário | Atualizações de DB e regeneração |
| Atribuição A/B | Cookie define a variante antes do render | Análise estatística e decisão de receita |
| Autenticação leve | Preview e admin podem ser bloqueados cedo | Criação de sessão e auditoria |
| Entrada de webhook | Uma assinatura pequena rejeita requisições ruins | Pagamento, e-mail, retentativas |
Inclua essa tabela no prompt para Claude Code. O resultado fica mais fácil de revisar porque o trabalho do Edge e o trabalho da origem já estão separados.
flowchart LR
User["User request"] --> Edge["Edge runtime"]
Edge --> Geo["Country / language branch"]
Edge --> Cache["Short cache"]
Edge --> Gate["Light auth gate"]
Edge --> Origin["Origin API / database"]
Origin --> Queue["Queue or background work"]
Prompt para o Claude Code
Em código Edge, o prompt deve explicar restrições, não apenas pedir velocidade. Claude Code gera código rápido, mas cache keys, ramificações regionais, secrets e comandos de verificação costumam escapar quando não aparecem como requisitos.
Implement a small Cloudflare Workers + TypeScript Edge runtime API.
Files:
- wrangler.toml
- src/index.ts
Requirements:
- GET /health returns JSON
- GET /api/edge-content returns locale and CTA copy based on country
- Use request.cf.country when Cloudflare provides it
- Also support a CF-IPCountry header for local curl verification
- Cache each locale separately for 60 seconds with the Cache API
- Return cache hit/miss through X-Edge-Cache
- Use Web APIs such as Request, Response, URL, and crypto; do not use Node-only APIs
- Include at least three curl or build commands that verify the behavior
Do not:
- Use pseudocode
- Hard-code API tokens or secrets
- Treat country code as proof for billing, permissions, or legal decisions
Explique alguns termos no próprio pedido. runtime é o ambiente onde o código roda. cache key é o nome usado para encontrar uma resposta em cache. colo é o identificador de data center da Cloudflare. Essas definições ajudam Claude Code a produzir comentários e notas de entrega mais claras.
Exemplo copiável de Cloudflare Workers
O Worker abaixo é pequeno de propósito. /api/edge-content lê o país a partir dos metadados da Cloudflare ou de um header local de teste, transforma isso em locale e salva a resposta por 60 segundos com Cache API. O header CF-IPCountry permite testar o desvio regional com curl antes do deploy.
name = "claude-edge-router"
main = "src/index.ts"
compatibility_date = "2026-06-02"
[vars]
DEFAULT_LOCALE = "en"
// src/index.ts
export interface Env {
DEFAULT_LOCALE: string;
}
type Locale = "ja" | "en" | "zh" | "ko" | "es" | "fr" | "de" | "pt" | "hi" | "id";
type CfRequest = Request & {
cf?: {
country?: string;
colo?: string;
city?: string;
};
};
const SUPPORTED_LOCALES = new Set<Locale>([
"ja",
"en",
"zh",
"ko",
"es",
"fr",
"de",
"pt",
"hi",
"id",
]);
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/health") {
return json({ ok: true, runtime: "cloudflare-workers" });
}
if (url.pathname === "/api/edge-content") {
return handleEdgeContent(request, env, ctx);
}
return json({ error: "not_found" }, 404);
},
} satisfies ExportedHandler<Env>;
async function handleEdgeContent(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
const url = new URL(request.url);
const country = getCountry(request);
const locale = localeFromCountry(country, env.DEFAULT_LOCALE);
const cacheKey = buildCacheKey(request, locale);
const cached = await caches.default.match(cacheKey);
if (cached) {
return withHeaders(cached, {
"X-Edge-Cache": "HIT",
"X-Edge-Locale": locale,
});
}
const body = {
locale,
country,
colo: getColo(request),
path: url.pathname,
cta: localizedCta(locale),
generatedAt: new Date().toISOString(),
};
const response = json(body, 200, {
"Cache-Control": "public, max-age=0, s-maxage=60, stale-while-revalidate=300",
"X-Edge-Cache": "MISS",
"X-Edge-Locale": locale,
});
ctx.waitUntil(caches.default.put(cacheKey, response.clone()));
return response;
}
function buildCacheKey(request: Request, locale: Locale): Request {
const url = new URL(request.url);
url.search = "";
url.pathname = `/__edge-cache/${locale}${url.pathname}`;
return new Request(url.toString(), { method: "GET" });
}
function getCountry(request: Request): string {
const cf = (request as CfRequest).cf;
return (
request.headers.get("CF-IPCountry") ||
request.headers.get("x-country") ||
cf?.country ||
"US"
).toUpperCase();
}
function getColo(request: Request): string {
return (request as CfRequest).cf?.colo || "local";
}
function localeFromCountry(country: string, fallback: string): Locale {
const normalizedFallback = SUPPORTED_LOCALES.has(fallback as Locale)
? (fallback as Locale)
: "en";
switch (country) {
case "JP":
return "ja";
case "CN":
case "TW":
case "HK":
return "zh";
case "KR":
return "ko";
case "ES":
case "MX":
case "AR":
return "es";
case "FR":
return "fr";
case "DE":
return "de";
case "BR":
case "PT":
return "pt";
case "IN":
return "hi";
case "ID":
return "id";
default:
return normalizedFallback;
}
}
function localizedCta(locale: Locale): string {
const messages: Record<Locale, string> = {
ja: "Claude Code教材を見る",
en: "Explore Claude Code templates",
zh: "查看 Claude Code 教材",
ko: "Claude Code 템플릿 보기",
es: "Ver plantillas de Claude Code",
fr: "Voir les modèles Claude Code",
de: "Claude Code Vorlagen ansehen",
pt: "Ver modelos de Claude Code",
hi: "Claude Code टेम्पलेट देखें",
id: "Lihat template Claude Code",
};
return messages[locale];
}
function json(data: unknown, status = 200, headers: HeadersInit = {}): Response {
return new Response(JSON.stringify(data, null, 2), {
status,
headers: {
"Content-Type": "application/json; charset=utf-8",
"X-Content-Type-Options": "nosniff",
...headers,
},
});
}
function withHeaders(response: Response, headers: Record<string, string>): Response {
const next = new Response(response.body, response);
for (const [key, value] of Object.entries(headers)) {
next.headers.set(key, value);
}
return next;
}
O detalhe importante é a cache key: ela contém locale. Sem isso, uma CTA japonesa poderia ser entregue a um visitante em português ou inglês. A query também é removida para que parâmetros como utm_source não quebrem a cache em centenas de entradas inúteis.
Levar o padrão para Vercel e Deno
Vercel Edge Middleware é útil antes do render da página. Ele pode definir headers, persistir um bucket A/B e redirecionar uma rota regional. Respeite as restrições do Edge Runtime e evite pacotes que dependam de APIs exclusivas de Node.
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};
export function middleware(request: NextRequest) {
const country = request.headers.get("x-vercel-ip-country") || "US";
const bucket = request.cookies.get("edge_bucket")?.value || chooseBucket();
const response = NextResponse.next();
response.headers.set("x-edge-country", country);
response.headers.set("x-edge-bucket", bucket);
response.cookies.set("edge_bucket", bucket, {
maxAge: 60 * 60 * 24 * 30,
sameSite: "lax",
secure: true,
});
if (country === "JP" && request.nextUrl.pathname === "/pricing") {
return NextResponse.redirect(new URL("/jp/pricing", request.url));
}
return response;
}
function chooseBucket(): "a" | "b" {
const bytes = new Uint8Array(1);
crypto.getRandomValues(bytes);
return bytes[0] < 128 ? "a" : "b";
}
No Deno Deploy, mantenha o formato com Request e Response, mas não copie campos específicos da Cloudflare como request.cf. Headers e variáveis de ambiente mudam por provedor, então precisam aparecer no prompt.
// main.ts
Deno.serve((request: Request) => {
const url = new URL(request.url);
const country = request.headers.get("x-country") || "US";
if (url.pathname !== "/api/edge-content") {
return Response.json({ error: "not_found" }, { status: 404 });
}
return Response.json({
runtime: "deno-deploy",
country,
message: country === "JP" ? "Japan entry" : "Default edge entry",
});
});
Comandos de verificação
Código Edge deve ser verificado em tipos, HTTP local, desvio regional, headers de cache e prontidão de deploy. Peça ao Claude Code para deixar essa evidência na entrega.
npm create cloudflare@latest claude-edge-router -- --type=hello-world
cd claude-edge-router
npm install -D typescript wrangler
npx wrangler types
npx tsc --noEmit
npx wrangler dev
Em outro terminal, execute curl.
curl -i http://127.0.0.1:8787/health
curl -i -H "CF-IPCountry: JP" http://127.0.0.1:8787/api/edge-content
curl -i -H "CF-IPCountry: US" http://127.0.0.1:8787/api/edge-content
curl -i -H "CF-IPCountry: JP" "http://127.0.0.1:8787/api/edge-content?utm_source=test"
npx wrangler deploy --dry-run
O comportamento esperado é simples: a primeira requisição para locale e path retorna X-Edge-Cache: MISS; a próxima retorna HIT. JP vira ja, US vira en, e a query de tracking não cria uma entrada separada.
Armadilhas comuns
A primeira armadilha é colocar trabalho demais no Edge. Chamadas longas a LLMs, ORM pesado, PDF, imagem e cobrança complexa costumam pertencer a uma API de origem ou fila. Edge deve ser a porta de entrada, não o backend inteiro.
A segunda é uma cache key ampla ou estreita demais. Se locale, sessão, preço ou bucket experimental mudam a resposta, precisam estar na chave. Se ruído como utm_* ou timestamp entra na chave, a cache quase nunca acerta.
A terceira é confiar demais na geografia. request.cf.country e x-vercel-ip-country são úteis para defaults de experiência, mas não provam imposto, idade, permissão ou cobrança. VPN, proxy corporativo e rota de CDN podem mudar o país observado.
A quarta é dar ao Claude Code apenas o nome do provedor. “Faça com Workers” não diz se você quer Cache API, KV, D1, compatibilidade com Vercel ou fallback para origem. Para decidir a fronteira, compare com funções serverless com Claude Code e otimização de performance.
Caminho de receita e próximos passos
Em um site multilíngue de conteúdo, Edge runtime também melhora o caminho de receita. Você pode localizar o texto do PDF gratuito, enviar o leitor ao idioma certo, normalizar parâmetros de anúncio antes do cache e manter CTAs de templates rápidas.
Para materiais reutilizáveis, veja os produtos ClaudeCodeLab. Para equipes que querem padronizar prompts, regras de revisão e a fronteira entre Edge e Node, veja treinamento e consultoria Claude Code. Para começar com um fluxo curto, use a folha gratuita.
Resultado do teste real
Nesta atualização, Masa testou o Worker local alternando CF-IPCountry: JP e CF-IPCountry: US, verificando locale, X-Edge-Cache e a cache key sem parâmetros de tracking. O achado útil foi que, em local, os headers de teste devem ser lidos antes de request.cf.country; caso contrário, a ramificação por país pode parecer presa em checagens repetidas. A chave também usa /__edge-cache/${locale}${pathname} para não misturar conteúdo regional. Ao pedir isso ao Claude Code, peça revisão conjunta de prioridade de headers, ramificação regional e cache key.
Resumo
Edge computing não é mover tudo para a borda. É colocar pequenas decisões de requisição perto do usuário e manter trabalho pesado e decisões finais na API normal. Dê ao Claude Code limites do runtime, regras de cache key, ramificações regionais e comandos de verificação desde o início. O resultado será mais rápido e muito mais fácil de revisar.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Permission receipt no Claude Code: escopo, prova e rollback
Padrão de permission receipt para Claude Code: ações permitidas, limites de aprovação, comandos de prova, rollback e CTA de receita.
Agent Harness seguro para Claude Code e Codex: permissoes, verificacao e rollback
Monte uma base segura para agentes com Claude Code e Codex usando politicas, plano, verificacao e recuperacao.
Subagentes no Claude Code: guia prático para delegar trabalho com segurança
Guia prático de subagentes no Claude Code para dividir artigos e código: regras, prompts, riscos e checklist.