DEV Community

Alex Spinov
Alex Spinov

Posted on

Cloudflare Workers Has a Free API You Should Know About

Cloudflare Workers run JavaScript at the edge in 300+ locations — with 100K free requests per day and 0ms cold starts.

Basic Worker

export default {
  async fetch(request, env) {
    const url = new URL(request.url)

    if (url.pathname === '/api/hello') {
      return Response.json({ message: 'Hello from the edge!' })
    }

    if (url.pathname === '/api/geo') {
      return Response.json({
        country: request.cf.country,
        city: request.cf.city,
        timezone: request.cf.timezone
      })
    }

    return new Response('Not Found', { status: 404 })
  }
}
Enter fullscreen mode Exit fullscreen mode

KV — Global Key-Value Store

export default {
  async fetch(request, env) {
    // Write
    await env.MY_KV.put('user:123', JSON.stringify({ name: 'John' }), {
      expirationTtl: 3600 // 1 hour
    })

    // Read (cached globally, <10ms)
    const user = await env.MY_KV.get('user:123', 'json')

    // List keys
    const list = await env.MY_KV.list({ prefix: 'user:' })

    return Response.json(user)
  }
}
Enter fullscreen mode Exit fullscreen mode

D1 — SQLite at the Edge

export default {
  async fetch(request, env) {
    // Query
    const { results } = await env.DB.prepare(
      'SELECT * FROM users WHERE active = ?'
    ).bind(true).all()

    // Insert
    await env.DB.prepare(
      'INSERT INTO users (name, email) VALUES (?, ?)'
    ).bind('John', 'john@test.com').run()

    // Batch
    await env.DB.batch([
      env.DB.prepare('INSERT INTO logs (msg) VALUES (?)').bind('Event 1'),
      env.DB.prepare('INSERT INTO logs (msg) VALUES (?)').bind('Event 2')
    ])

    return Response.json(results)
  }
}
Enter fullscreen mode Exit fullscreen mode

R2 — S3-Compatible Storage

export default {
  async fetch(request, env) {
    if (request.method === 'PUT') {
      const body = await request.arrayBuffer()
      await env.MY_BUCKET.put('uploads/file.pdf', body, {
        httpMetadata: { contentType: 'application/pdf' }
      })
      return Response.json({ uploaded: true })
    }

    if (request.method === 'GET') {
      const object = await env.MY_BUCKET.get('uploads/file.pdf')
      if (!object) return new Response('Not Found', { status: 404 })
      return new Response(object.body, {
        headers: { 'Content-Type': object.httpMetadata.contentType }
      })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Durable Objects — Stateful Edge

export class ChatRoom {
  constructor(state, env) {
    this.state = state
    this.sessions = []
  }

  async fetch(request) {
    const [client, server] = Object.values(new WebSocketPair())
    this.sessions.push(server)
    server.accept()

    server.addEventListener('message', (msg) => {
      for (const session of this.sessions) {
        if (session !== server) session.send(msg.data)
      }
    })

    return new Response(null, { status: 101, webSocket: client })
  }
}
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

An API company needed to add geolocation-based routing with <10ms latency globally. Traditional approach: servers in 5 regions, DNS-based routing, $500/month. Cloudflare Workers: code runs in 300+ locations automatically, request.cf gives location data, KV caches responses globally. Cost: $0 (free tier) to $5/month. Latency: <5ms everywhere.

Cloudflare Workers made the edge accessible to everyone.


Build Smarter Data Pipelines

Need to scrape websites, extract APIs, or automate data collection? Check out my ready-to-use scrapers on Apify — no coding required.

Custom scraping solution? Email me at spinov001@gmail.com — fast turnaround, fair prices.

Top comments (0)