Home > Cloudflare Workers
Slide 1 / 22
☁️

Cloudflare Workers

Serverless Edge Computing

2 Weeks - Complete Guide

Jalankan kode JavaScript, Python, C++, atau Rust di 200+ lokasi edge global tanpa manage server

Overview

Tujuan Pembelajaran

Kenapa Cloudflare Workers?

Minggu 1

Apa itu Edge Computing?

Edge Computing adalah paradigma komputasi yang mendekatkan processing data ke sumber data.

🖥️ Traditional Server

User di Jakarta → Server di US

Latency: 200-300ms

⚡ Edge Computing

User di Jakarta → Edge Singapore

Latency: 10-30ms

Cloudflare Edge Network

Minggu 1

Limitasi Workers

ResourceFree TierPaid Tier
Requests100,000/day10 juta/month
CPU Time10ms30 seconds
Memory128MB128MB

Yang Tidak Support

Minggu 1

Arsitektur Dasar Workers

Fetch Event (HTTP)

export default {
  async fetch(request, env, ctx) {
    return new Response("Hello from Workers!");
  }
};

Scheduled Event (Cron)

export default {
  async scheduled(event, env, ctx) {
    console.log("Cron triggered");
  }
};
Minggu 1

Membaca Request

export default {
  async fetch(request, env, ctx) {
    // HTTP Method
    const method = request.method;
    
    // URL Parsing
    const url = new URL(request.url);
    const pathname = url.pathname;
    const query = url.searchParams.get("q");
    
    // Headers
    const userAgent = request.headers.get("User-Agent");
    const cfCountry = request.headers.get("CF-IPCountry");
    
    // Body
    const body = await request.json();
    
    return new Response(JSON.stringify({ method, pathname }));
  }
};
Minggu 1

Membuat Response

// Basic
return new Response("Hello World!");

// JSON
return new Response(JSON.stringify({ status: "ok" }), {
  status: 200,
  headers: { "Content-Type": "application/json" }
});

// Redirect
return Response.redirect("https://example.com", 301);

// Error
return new Response("Not Found", { status: 404 });
Minggu 1

Wrangler CLI

Install & Setup

npm install -g wrangler
wrangler login

Init Project

wrangler init my-worker
cd my-worker

Commands

wrangler dev          # Local dev
wrangler deploy       # Deploy
wrangler logs         # View logs
Minggu 1

wrangler.toml

name = "my-worker"
main = "worker.js"
compatibility_date = "2024-01-01"

[vars]
APP_NAME = "My Worker"
VERSION = "1.0.0"

Struktur Project

my-worker/
├── worker.js        # Main script
├── wrangler.toml    # Config
└── package.json
Minggu 1

Environment Variables

Public (vars)

// wrangler.toml
[vars]
API_URL = "https://api.example.com"

// worker.js
const apiUrl = env.API_URL;

Private Secrets

# CLI
wrangler secret put API_KEY
# Input: (ketik nilai rahasia)
Minggu 1

Multiple Environments

# wrangler.toml
[env.staging]
name = "my-worker-staging"
vars = { ENVIRONMENT = "staging" }

[env.production]
name = "my-worker-production"
vars = { ENVIRONMENT = "production" }

Deploy Commands

wrangler deploy --env staging
wrangler deploy --env production
Minggu 1

Context Object

waitUntil - Background Tasks

export default {
  async fetch(request, env, ctx) {
    // Task berjalan di background
    ctx.waitUntil(
      fetch("https://webhook.example.com/log", {
        method: "POST",
        body: JSON.stringify({ url: request.url })
      })
    );
    
    return new Response("Processing...");
  }
};
Minggu 2

Use Case: Redirect

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    
    const redirects = {
      "/old-page": "/new-page",
      "/product-1": "https://other-site.com",
      "/legacy": "https://archive.example.com"
    };
    
    const destination = redirects[url.pathname];
    if (destination) {
      return Response.redirect(destination, 301);
    }
    
    return new Response("Not Found", { status: 404 });
  }
};
301 = permanent (SEO), 302 = temporary
Minggu 2

Use Case: API Proxy

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const backendUrl = `https://api.example.com${url.pathname}${url.search}`;
    
    const response = await fetch(backendUrl, {
      method: request.method,
      headers: {
        ...request.headers,
        "X-Custom-Header": "worker-proxy"
      },
      body: request.body
    });
    
    return new Response(response.body, {
      status: response.status,
      headers: {
        ...response.headers,
        "X-Proxied-By": "Cloudflare-Worker"
      }
    });
  }
};
Minggu 2

Use Case: A/B Testing

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const cookie = request.headers.get("Cookie");
    
    // Cek variant existing
    if (cookie?.includes("variant=A")) {
      return fetch(`https://site-a.com${url.pathname}`);
    }
    if (cookie?.includes("variant=B")) {
      return fetch(`https://site-b.com${url.pathname}`);
    }
    
    // Assign variant baru (50/50)
    const variant = Math.random() < 0.5 ? "A" : "B";
    const destination = variant === "A" 
      ? `https://site-a.com${url.pathname}`
      : `https://site-b.com${url.pathname}`;
    
    const response = await fetch(destination);
    
    // Set cookie
    const newHeaders = new Headers(response.headers);
    newHeaders.append("Set-Cookie", `variant=${variant}; Path=/; Max-Age=2592000`);
    
    return new Response(response.body, { headers: newHeaders });
  }
};
Minggu 2

Cloudflare KV

KV adalah key-value storage di edge. Untuk caching, session, konfigurasi.

Setup

# wrangler.toml
[[kv_namespaces]]
binding = "MY_KV"
id = "xxxxxx"

Usage

// Write
await env.MY_KV.put("key", "value", { expirationTtl: 3600 });

// Read
const value = await env.MY_KV.get("key");

// Delete
await env.MY_KV.delete("key");
Minggu 2

Cloudflare R2

R2 adalah object storage tanpa bandwidth charges.

Setup

# wrangler.toml
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"

Usage

// Upload
await env.MY_BUCKET.put("file.txt", "Hello World");

// Download
const object = await env.MY_BUCKET.get("file.txt");
const text = await object.text();
Minggu 2

Cloudflare D1

D1 adalah SQLite database di edge.

Setup

wrangler d1 create my-db

# wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-db"

Usage

// Select
const stmt = await env.DB.prepare("SELECT * FROM users WHERE id = ?");
const user = await stmt.bind(userId).first();

// Insert
await env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind("John").run();
Minggu 2

Scheduled Workers

Configure Cron

# wrangler.toml
[triggers]
crons = ["*/5 * * * *"]  # Every 5 minutes

# Cron examples:
# "*/5 * * * *"   = Every 5 minutes
# "0 * * * *"     = Every hour
# "0 0 * * *"     = Daily midnight

Handler

export default {
  async scheduled(event, env, ctx) {
    console.log("Triggered at:", event.scheduledTime);
    // Do something
  }
};
Minggu 2

Pricing

FeatureFreePaid
Requests100K/day$5/10M
KV Reads1M/month$0.20/1M
KV Writes1M/month$1.00/1M
R2 Storage1 GB$0.015/GB
Free tier sudah cukup untuk learning dan projects kecil.
Best Practices

Tips & Best Practices

Debugging

export default {
  async fetch(request, env, ctx) {
    console.log("Request URL:", request.url);
    // View di: wrangler logs
  }
};

🎉 Selesai!

Next Steps

1. Coba: wrangler init my-worker → wrangler dev

2. Eksplorasi: KV, R2, D1 sesuai kebutuhan

3. Deploy ke production dengan custom domain

Kuis: Cloudflare Workers

Apa Workers di Cloudflare?

Bahasa apa yang didukung Workers?

Apa keunggulan Workers dibanding Lambda?