Serverless Edge Computing
2 Weeks - Complete Guide
Jalankan kode JavaScript, Python, C++, atau Rust di 200+ lokasi edge global tanpa manage server
User di Jakarta → Server di US
Latency: 200-300ms
User di Jakarta → Edge Singapore
Latency: 10-30ms
| Resource | Free Tier | Paid Tier |
|---|---|---|
| Requests | 100,000/day | 10 juta/month |
| CPU Time | 10ms | 30 seconds |
| Memory | 128MB | 128MB |
export default {
async fetch(request, env, ctx) {
return new Response("Hello from Workers!");
}
};
export default {
async scheduled(event, env, ctx) {
console.log("Cron triggered");
}
};
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 }));
}
};
// 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 });
npm install -g wrangler
wrangler login
wrangler init my-worker
cd my-worker
wrangler dev # Local dev
wrangler deploy # Deploy
wrangler logs # View logs
name = "my-worker"
main = "worker.js"
compatibility_date = "2024-01-01"
[vars]
APP_NAME = "My Worker"
VERSION = "1.0.0"
my-worker/
├── worker.js # Main script
├── wrangler.toml # Config
└── package.json
// wrangler.toml
[vars]
API_URL = "https://api.example.com"
// worker.js
const apiUrl = env.API_URL;
# CLI
wrangler secret put API_KEY
# Input: (ketik nilai rahasia)
# wrangler.toml
[env.staging]
name = "my-worker-staging"
vars = { ENVIRONMENT = "staging" }
[env.production]
name = "my-worker-production"
vars = { ENVIRONMENT = "production" }
wrangler deploy --env staging
wrangler deploy --env production
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...");
}
};
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 });
}
};
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"
}
});
}
};
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 });
}
};
# wrangler.toml
[[kv_namespaces]]
binding = "MY_KV"
id = "xxxxxx"
// 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");
# wrangler.toml
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"
// 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();
wrangler d1 create my-db
# wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-db"
// 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();
# wrangler.toml
[triggers]
crons = ["*/5 * * * *"] # Every 5 minutes
# Cron examples:
# "*/5 * * * *" = Every 5 minutes
# "0 * * * *" = Every hour
# "0 0 * * *" = Daily midnight
export default {
async scheduled(event, env, ctx) {
console.log("Triggered at:", event.scheduledTime);
// Do something
}
};
| Feature | Free | Paid |
|---|---|---|
| Requests | 100K/day | $5/10M |
| KV Reads | 1M/month | $0.20/1M |
| KV Writes | 1M/month | $1.00/1M |
| R2 Storage | 1 GB | $0.015/GB |
wrangler logsexport default {
async fetch(request, env, ctx) {
console.log("Request URL:", request.url);
// View di: wrangler logs
}
};
Next Steps
1. Coba: wrangler init my-worker → wrangler dev
2. Eksplorasi: KV, R2, D1 sesuai kebutuhan
3. Deploy ke production dengan custom domain
Apa Workers di Cloudflare?
Bahasa apa yang didukung Workers?
Apa keunggulan Workers dibanding Lambda?