Voltar para o Blog

Edge Computing com JavaScript: Cloudflare Workers, Vercel Edge e Deno Deploy

Olá HaWkers, edge computing está transformando como desenvolvemos aplicações web. Em vez de processar requisições em um servidor central distante, o código roda em pontos de presença distribuídos globalmente, reduzindo latência drasticamente.

E o melhor: você pode usar JavaScript para isso. Vamos explorar as principais plataformas e entender quando usar cada uma.

O Que É Edge Computing

Edge computing move a computação para mais perto do usuário final. Em vez de uma requisição viajar milhares de quilômetros até um data center central, ela é processada no ponto de presença mais próximo.

Benefícios práticos:

  • Latência reduzida (< 50ms globalmente)
  • Melhor experiência do usuário
  • Menor carga no servidor de origem
  • Possibilidade de personalização por região
  • Cold starts praticamente inexistentes

Casos de uso ideais:

  • APIs de baixa latência
  • Autenticação e autorização
  • Redirecionamentos inteligentes
  • A/B testing
  • Personalização de conteúdo
  • Rate limiting
  • Transformação de respostas

Cloudflare Workers

O Cloudflare Workers foi pioneiro no edge computing com JavaScript. Usa o runtime V8 isolates, que é diferente do Node.js tradicional.

Características

Pontos fortes:

  • Maior rede de edge (300+ localizações)
  • Cold start praticamente zero
  • Preço competitivo
  • Ecossistema maduro (KV, Durable Objects, R2)
  • Suporte a WebSockets

Limitações:

  • Runtime não é Node.js (algumas APIs diferentes)
  • Limite de CPU time por requisição
  • Curva de aprendizado para recursos avançados

Exemplo Prático

// src/index.js - Cloudflare Worker
export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);

    // Roteamento básico
    if (url.pathname === '/api/hello') {
      return new Response(JSON.stringify({
        message: 'Hello from the edge!',
        location: request.cf?.city || 'unknown',
        country: request.cf?.country || 'unknown',
      }), {
        headers: { 'Content-Type': 'application/json' },
      });
    }

    // Cache com KV Storage
    if (url.pathname.startsWith('/api/cached/')) {
      const key = url.pathname.replace('/api/cached/', '');
      const cached = await env.MY_KV.get(key);

      if (cached) {
        return new Response(cached, {
          headers: {
            'Content-Type': 'application/json',
            'X-Cache': 'HIT',
          },
        });
      }

      // Buscar do origin e cachear
      const data = await fetchFromOrigin(key);
      await env.MY_KV.put(key, JSON.stringify(data), {
        expirationTtl: 3600, // 1 hora
      });

      return new Response(JSON.stringify(data), {
        headers: {
          'Content-Type': 'application/json',
          'X-Cache': 'MISS',
        },
      });
    }

    return new Response('Not Found', { status: 404 });
  },
};

async function fetchFromOrigin(key) {
  const response = await fetch(`https://api.origin.com/data/${key}`);
  return response.json();
}

Configuração

# wrangler.toml
name = "my-edge-api"
main = "src/index.js"
compatibility_date = "2025-11-01"

[[kv_namespaces]]
binding = "MY_KV"
id = "abc123"

[vars]
API_KEY = "your-api-key"

Vercel Edge Functions

Vercel Edge Functions integra-se perfeitamente com Next.js e outros frameworks. Usa o mesmo runtime V8 isolates.

Características

Pontos fortes:

  • Integração nativa com Next.js
  • Deploy automático via Git
  • UI excelente para monitoramento
  • Middleware poderoso
  • Fácil de começar

Limitações:

  • Menos localizações que Cloudflare
  • Pricing pode escalar rápido
  • Menos recursos de storage nativos

Exemplo com Next.js

// middleware.ts - Vercel Edge Middleware
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const { pathname, geo } = request.nextUrl;

  // Geolocalização
  const country = geo?.country || 'US';
  const city = geo?.city || 'Unknown';

  // Redirecionamento por região
  if (pathname === '/' && country === 'BR') {
    return NextResponse.redirect(new URL('/pt-br', request.url));
  }

  // A/B Testing
  const bucket = request.cookies.get('ab-bucket')?.value;
  if (!bucket && pathname === '/landing') {
    const newBucket = Math.random() < 0.5 ? 'A' : 'B';
    const response = NextResponse.rewrite(
      new URL(`/landing/${newBucket}`, request.url)
    );
    response.cookies.set('ab-bucket', newBucket, {
      maxAge: 60 * 60 * 24 * 30, // 30 dias
    });
    return response;
  }

  // Headers customizados
  const response = NextResponse.next();
  response.headers.set('X-Geo-Country', country);
  response.headers.set('X-Geo-City', city);

  return response;
}

export const config = {
  matcher: ['/', '/landing/:path*', '/api/:path*'],
};

Edge API Route

// app/api/edge/route.ts
import { NextRequest } from 'next/server';

export const runtime = 'edge';

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const query = searchParams.get('q');

  // Processamento leve no edge
  const results = await searchIndex(query);

  return Response.json({
    results,
    processed_at: new Date().toISOString(),
    edge_location: request.geo?.city,
  });
}

async function searchIndex(query: string | null) {
  // Lógica de busca otimizada para edge
  return [];
}

Deno Deploy

Deno Deploy usa o runtime Deno, oferecendo TypeScript nativo e APIs modernas.

Características

Pontos fortes:

  • TypeScript nativo sem build
  • APIs Web padrão (fetch, Request, Response)
  • Deno KV integrado
  • Broadcast Channels para comunicação
  • Free tier generoso

Limitações:

  • Ecossistema menor que Node.js
  • Menos integrações empresariais
  • Curva de aprendizado se vier do Node.js

Exemplo Prático

// main.ts - Deno Deploy
import { serve } from "https://deno.land/std@0.220.0/http/server.ts";

const kv = await Deno.openKv();

async function handler(request: Request): Promise<Response> {
  const url = new URL(request.url);

  // API de Rate Limiting
  if (url.pathname.startsWith('/api/')) {
    const clientIP = request.headers.get('x-forwarded-for') || 'unknown';
    const rateLimit = await checkRateLimit(clientIP);

    if (!rateLimit.allowed) {
      return new Response(JSON.stringify({
        error: 'Rate limit exceeded',
        retry_after: rateLimit.retryAfter,
      }), {
        status: 429,
        headers: {
          'Content-Type': 'application/json',
          'Retry-After': String(rateLimit.retryAfter),
        },
      });
    }
  }

  // Rota principal
  if (url.pathname === '/api/data') {
    const data = await fetchData();
    return Response.json(data);
  }

  // Cache com Deno KV
  if (url.pathname.startsWith('/api/cached/')) {
    const key = url.pathname.replace('/api/cached/', '');
    const cached = await kv.get(['cache', key]);

    if (cached.value) {
      return Response.json(cached.value, {
        headers: { 'X-Cache': 'HIT' },
      });
    }

    const data = await fetchFromOrigin(key);
    await kv.set(['cache', key], data, {
      expireIn: 3600 * 1000, // 1 hora
    });

    return Response.json(data, {
      headers: { 'X-Cache': 'MISS' },
    });
  }

  return new Response('Not Found', { status: 404 });
}

async function checkRateLimit(clientIP: string) {
  const key = ['ratelimit', clientIP];
  const now = Date.now();
  const windowMs = 60000; // 1 minuto
  const maxRequests = 100;

  const entry = await kv.get<{ count: number; resetAt: number }>(key);

  if (!entry.value || now > entry.value.resetAt) {
    await kv.set(key, { count: 1, resetAt: now + windowMs });
    return { allowed: true };
  }

  if (entry.value.count >= maxRequests) {
    return {
      allowed: false,
      retryAfter: Math.ceil((entry.value.resetAt - now) / 1000),
    };
  }

  await kv.set(key, {
    count: entry.value.count + 1,
    resetAt: entry.value.resetAt,
  });

  return { allowed: true };
}

async function fetchData() {
  return { message: 'Hello from Deno Deploy!' };
}

async function fetchFromOrigin(key: string) {
  return { key, data: 'origin data' };
}

serve(handler);

Comparativo das Plataformas

Performance e Rede

Plataforma Localizações Cold Start CPU Limit
Cloudflare 300+ ~0ms 50ms
Vercel Edge 100+ ~25ms 25ms
Deno Deploy 35+ ~10ms 50ms

Storage e Recursos

Plataforma KV Storage Durable Objects Database
Cloudflare ✅ KV D1 (SQLite)
Vercel Via Upstash Via integração
Deno ✅ Deno KV Deno KV

Pricing (Tier Gratuito)

Plataforma Requests/dia CPU Time Bandwidth
Cloudflare 100k 10ms/req Ilimitado
Vercel 100k - 100GB
Deno 1M/mês - 100GB

Quando Usar Edge Computing

Use Edge Quando:

  • Precisa de latência global baixa
  • Faz transformação leve de requisições
  • Implementa autenticação/autorização
  • Serve conteúdo personalizado por região
  • Precisa de rate limiting distribuído
  • Faz redirecionamentos inteligentes

Evite Edge Quando:

  • Precisa de processamento pesado de CPU
  • Requer conexão com banco de dados tradicional
  • Tem dependências Node.js incompatíveis
  • Precisa de processamento em batch
  • Tem requisitos de compliance que exigem região específica

Padrões de Arquitetura

Edge + Origin

// Pattern: Edge como gateway, Origin para lógica pesada
async function handler(request: Request) {
  // Validação rápida no edge
  const authResult = await validateAuth(request);
  if (!authResult.valid) {
    return new Response('Unauthorized', { status: 401 });
  }

  // Cache check no edge
  const cacheKey = getCacheKey(request);
  const cached = await cache.get(cacheKey);
  if (cached) {
    return new Response(cached);
  }

  // Forward para origin se necessário
  const originResponse = await fetch('https://origin.example.com/api', {
    headers: {
      'Authorization': `Bearer ${authResult.token}`,
      'X-User-Id': authResult.userId,
    },
  });

  // Cache response no edge
  const data = await originResponse.text();
  await cache.put(cacheKey, data, { ttl: 300 });

  return new Response(data);
}

Conclusão

Edge computing com JavaScript oferece uma forma poderosa de melhorar a performance de aplicações web. A escolha da plataforma depende do seu contexto:

Cloudflare Workers é ideal para quem precisa da maior rede de distribuição e recursos avançados como Durable Objects.

Vercel Edge Functions é perfeito para projetos Next.js que querem integração seamless e boa experiência de desenvolvedor.

Deno Deploy é excelente para quem quer TypeScript nativo e está confortável com o ecossistema Deno.

A boa notícia é que todas as plataformas usam APIs Web padrão, então muito do código é portável entre elas.

Se você está interessado em explorar mais sobre arquiteturas modernas com JavaScript, recomendo conferir o artigo Node.js vs Deno vs Bun: Qual Runtime JavaScript Escolher em 2025 para entender melhor os runtimes que alimentam essas plataformas de edge.

Bora pra cima! 🦅

Comentários (0)

Esse artigo ainda não possui comentários 😢. Seja o primeiro! 🚀🦅

Adicionar comentário