| name | cloudflare-expert |
| version | 1.0.0 |
| description | Expert-level Cloudflare Workers, CDN, edge computing, and security services |
| category | cloud |
| tags | ["cloudflare","edge-computing","cdn","workers","waf"] |
| allowed-tools | ["Read","Write","Edit","Bash(wrangler:*)"] |
Cloudflare Expert
Expert guidance for Cloudflare Workers, edge computing, CDN optimization, and Cloudflare security services.
Core Concepts
Cloudflare Services
- Cloudflare Workers (serverless edge computing)
- CDN and caching
- DDoS protection
- Web Application Firewall (WAF)
- DNS management
- Load balancing
- Workers KV (key-value storage)
- Durable Objects
Edge Computing
- Deploy code globally
- Reduce latency
- Process at the edge
- Distributed state
- Real-time applications
Developer Tools
- Wrangler CLI
- Workers Playground
- Edge APIs
- Analytics and logs
Cloudflare Workers
export default {
async fetch(request, env, ctx) {
return new Response('Hello from Cloudflare Workers!', {
headers: { 'Content-Type': 'text/plain' }
});
}
};
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
switch (url.pathname) {
case '/api/users':
return handleUsers(request, env);
case '/api/posts':
return handlePosts(request, env);
default:
return new Response('Not Found', { status: 404 });
}
}
};
async function handleUsers(request, env) {
if (request.method === 'GET') {
const users = await env..(, { : });
(.(users), {
: { : }
});
}
(request. === ) {
body = request.();
env..(, .(body));
(, { : });
}
(, { : });
}
Workers KV Storage
export default {
async fetch(request, env, ctx) {
await env.MY_KV.put('key', 'value');
await env.MY_KV.put('key', 'value', {
metadata: { userId: '123' },
expirationTtl: 3600
});
const value = await env.MY_KV.get('key');
const jsonValue = await env.MY_KV.get('key', { type: 'json' });
const { value, metadata } = await env.MY_KV.getWithMetadata('key');
await env.MY_KV.delete('key');
const keys = await env..({ : });
(.({ value, keys }));
}
};
{
() {
. = kv;
}
() {
cached = ..(key, { : });
(cached) cached;
data = ();
..(key, .(data), {
: ttl
});
data;
}
}
{
() {
cache = (env.);
data = cache.(, () => {
response = ();
response.();
}, );
(.(data));
}
};
Durable Objects
export class Counter {
constructor(state, env) {
this.state = state;
this.value = 0;
}
async initialize() {
this.value = await this.state.storage.get('value') || 0;
}
async fetch(request) {
await this.initialize();
const url = new URL(request.url);
if (url.pathname === '/increment') {
this.value++;
await this.state.storage.put('value', this.value);
return new Response(String(this.value));
}
(url. === ) {
.--;
...(, .);
((.));
}
((.));
}
}
{
() {
. = state;
. = [];
}
() {
(request..() !== ) {
(, { : });
}
pair = ();
[client, server] = .(pair);
.(server);
(, {
: ,
: client
});
}
() {
websocket.();
..(websocket);
websocket.(, (msg) => {
( session .) {
{
session.(msg.);
} (err) {
. = ..( s !== session);
}
}
});
}
}
{
() {
url = (request.);
roomId = url..();
id = env..(roomId);
stub = env..(id);
stub.(request);
}
};
Request/Response Handling
function handleCORS(request) {
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
};
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
return corsHeaders;
}
async function authenticate(request, env) {
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
if (!token) {
return new Response('Unauthorized', { status: 401 });
}
try {
const payload = await verifyJWT(token, env.JWT_SECRET);
return payload;
} catch (err) {
return (, { : });
}
}
{
() {
. = kv;
}
() {
key = ;
now = .();
windowMs = windowSeconds * ;
data = ..(key, { : });
(!data || now - data. > windowMs) {
..(key, .({
: ,
: now
}), { : windowSeconds });
;
}
(data. >= maxRequests) {
;
}
data.++;
..(key, .(data), {
: windowSeconds
});
;
}
}
{
() {
corsHeaders = (request);
(request. === ) corsHeaders;
rateLimiter = (env.);
clientIP = request..();
allowed = rateLimiter.(clientIP, , );
(!allowed) {
(, {
: ,
: corsHeaders
});
}
user = (request, env);
(user ) {
user;
}
response = (request, env, user);
.(corsHeaders).( {
response..(key, value);
});
response;
}
};
Caching Strategies
async function cacheFirst(request) {
const cache = caches.default;
let response = await cache.match(request);
if (!response) {
response = await fetch(request);
response = new Response(response.body, response);
response.headers.set('Cache-Control', 'max-age=3600');
await cache.put(request, response.clone());
}
return response;
}
async function staleWhileRevalidate(request, ctx) {
const cache = caches.default;
let response = await cache.match(request);
ctx.waitUntil(
fetch(request).then(freshResponse => {
const clonedResponse = freshResponse.clone();
cache.put(request, clonedResponse);
})
);
if (response) {
return response;
}
return (request);
}
() {
url = (request.);
url. = ;
userAgent = request..();
isMobile = .(userAgent);
url..(, isMobile ? : );
(url.(), request);
}
{
() {
cacheKey = (request);
(request..()) {
(cacheKey, ctx);
}
(cacheKey);
}
};
Edge Functions
export default {
async fetch(request, env, ctx) {
const response = await fetch(request);
return new HTMLRewriter()
.on('head', new HeadInjector())
.transform(response);
}
};
class HeadInjector {
element(element) {
element.append(
'<script>console.log("Injected at edge!");</script>',
{ html: true }
);
}
}
export default {
async fetch(request, env, ctx) {
const country = request.cf.country;
const apiEndpoint = {
'US': 'https://us-api.example.com',
'EU': 'https://eu-api.example.com',
'default': 'https://global-api.example.com'
}[country] || 'https://global-api.example.com';
const url = new URL(request.url);
apiUrl = (url., apiEndpoint);
(apiUrl, request);
}
};
{
() {
url = (request.);
variant = request..()?.()?.[];
(!variant) {
variant = .() < ? : ;
}
response = ();
newResponse = (response., response);
newResponse..(, );
newResponse;
}
};
Wrangler CLI
wrangler init my-worker
wrangler dev
wrangler publish
wrangler publish --env production
wrangler tail
wrangler kv:namespace create "MY_KV"
wrangler kv:key put --namespace-id=<id> "key" "value"
wrangler kv:key get --namespace-id=<id> "key"
wrangler publish --new-class Counter
wrangler secret put SECRET_NAME
wrangler.toml Configuration
name = "my-worker"
main = "src/index.js"
compatibility_date = "2024-01-01"
kv_namespaces = [
{ binding = "MY_KV", id = "xxxxxxxx" },
{ binding = "CACHE_KV", id = "yyyyyyyy" }
]
[durable_objects]
bindings = [
{ name = "COUNTER", class_name = "Counter" },
{ name = "CHAT_ROOM", class_name = "ChatRoom" }
]
[[migrations]]
tag = "v1"
new_classes = ["Counter", "ChatRoom"]
[vars]
ENVIRONMENT = "production"
routes = [
{ pattern = "example.com/*", zone_name = "example.com" }
]
[triggers]
crons = ["0 */6 * * *"]
Best Practices
Performance
- Cache aggressively at the edge
- Minimize worker execution time
- Use Workers KV for global data
- Implement connection pooling
- Optimize cache keys
- Use stale-while-revalidate
- Minimize external requests
Security
- Validate all inputs
- Implement rate limiting
- Use secrets for sensitive data
- Set security headers
- Implement CORS properly
- Use HTTPS everywhere
- Log security events
Development
- Use TypeScript for type safety
- Test locally with wrangler dev
- Implement proper error handling
- Monitor worker metrics
- Use environment variables
- Version your workers
- Document API endpoints
Anti-Patterns
❌ Storing large data in KV frequently
❌ Long-running computations in workers
❌ Not implementing caching
❌ Hardcoding secrets
❌ Ignoring rate limits
❌ No error handling
❌ Excessive external API calls
Resources