# Workers Playground Patterns

## JSON API

```javascript
export default {
  async fetch(request) {
    const url = new URL(request.url)
    if (url.pathname === '/api/hello') return Response.json({ message: 'Hello' })
    if (url.pathname === '/api/echo' && request.method === 'POST') {
      return Response.json({ received: await request.json() })
    }
    return Response.json({ error: 'Not found' }, { status: 404 })
  },
}
```

## Router Pattern

```javascript
const routes = {
  '/': () => new Response('Home'),
  '/api/users': () => Response.json([{ id: 1, name: 'Alice' }]),
}

export default {
  async fetch(request) {
    const handler = routes[new URL(request.url).pathname]
    return handler ? handler() : new Response('Not Found', { status: 404 })
  },
}
```

## Proxy Pattern

```javascript
export default {
  async fetch(request) {
    const url = new URL(request.url)
    url.hostname = 'api.example.com'
    return fetch(url.toString(), {
      method: request.method,
      headers: request.headers,
      body: request.body,
    })
  },
}
```

## CORS Handling

```javascript
export default {
  async fetch(request) {
    if (request.method === 'OPTIONS') {
      return new Response(null, {
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
          'Access-Control-Allow-Headers': 'Content-Type, Authorization',
        },
      })
    }
    const response = await fetch('https://api.example.com', request)
    const modified = new Response(response.body, response)
    modified.headers.set('Access-Control-Allow-Origin', '*')
    return modified
  },
}
```

## Caching

```javascript
export default {
  async fetch(request) {
    if (request.method !== 'GET') return fetch(request)
    const cache = caches.default
    let response = await cache.match(request)
    if (!response) {
      response = await fetch('https://api.example.com')
      if (response.status === 200) await cache.put(request, response.clone())
    }
    return response
  },
}
```

## Hono Framework

```javascript
import { Hono } from 'https://esm.sh/hono@3'
const app = new Hono()
app.get('/', (c) => c.text('Hello'))
app.get('/api/users/:id', (c) => c.json({ id: c.req.param('id') }))
app.notFound((c) => c.json({ error: 'Not found' }, 404))
export default app
```

## Authentication

```javascript
export default {
  async fetch(request) {
    const auth = request.headers.get('Authorization')
    if (!auth?.startsWith('Bearer ')) {
      return Response.json({ error: 'Unauthorized' }, { status: 401 })
    }
    const token = auth.substring(7)
    if (token !== 'secret-token') {
      return Response.json({ error: 'Invalid token' }, { status: 403 })
    }
    return Response.json({ message: 'Authenticated' })
  },
}
```

## Error Handling

```javascript
export default {
  async fetch(request) {
    try {
      const response = await fetch('https://api.example.com')
      if (!response.ok) throw new Error(`API returned ${response.status}`)
      return response
    } catch (error) {
      return Response.json({ error: error.message }, { status: 500 })
    }
  },
}
```

**Note:** In-memory state (Maps, variables) resets on Worker cold start. Use Durable Objects or KV for persistence.
