Package Exports
- @whi/cf-routing
- @whi/cf-routing/lib/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@whi/cf-routing) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Cloudflare Workers Routing
Class-based routing framework for Cloudflare Workers and Durable Objects built on itty-router.
Features
- Class-based Route Handlers - Organize routes using ES6 classes
- Built-in Error Handling - Automatic JSON error responses with proper status codes
- CORS Support - Pre-configured CORS headers for all responses
- Type Safety - Full TypeScript support with generic types
- Durable Objects - First-class support for Durable Object routing
- Middleware - Easy middleware registration with error handling
- Method Chaining - Fluent API for route registration
Installation
npm install @whi/cf-routingQuick Start
Worker Router
import { WorkerRouter, RouteHandler } from '@whi/cf-routing';
class HealthHandler extends RouteHandler {
async get() {
return { status: 'healthy' };
}
}
const router = new WorkerRouter()
.defineRouteHandler('/health', HealthHandler)
.build();
export default {
async fetch(request, env, ctx) {
return router.fetch(request, env, ctx);
},
};Durable Object Router
import { DurableObjectRouter, DurableObjectRouteHandler } from '@whi/cf-routing';
class CounterHandler extends DurableObjectRouteHandler {
async get() {
return { count: await this.ctx.storage.get('count') || 0 };
}
async post() {
const count = await this.ctx.storage.get('count') || 0;
await this.ctx.storage.put('count', count + 1);
return { count: count + 1 };
}
}
export class Counter {
constructor(ctx, env) {
this.router = new DurableObjectRouter(ctx, env, 'counter')
.defineRouteHandler('/count', CounterHandler);
}
async fetch(request) {
return this.router.handle(request);
}
}Key Features
Route Handlers
Create route handlers by extending the base classes and implementing HTTP methods:
class UserHandler extends RouteHandler<Env, { id: string }> {
async get(request, env, params) {
return { userId: params.id };
}
async post(request, env, params) {
const body = await request.json();
return { userId: params.id, created: true };
}
}
router.defineRouteHandler('/users/:id', UserHandler);Automatic Error Handling
Throw HttpError for proper HTTP status codes:
import { HttpError } from '@whi/cf-routing';
async get(request, env, params) {
if (!params?.id) {
throw new HttpError(400, 'ID required');
}
// Errors automatically become JSON responses
}Response Customization
Customize status codes and headers via this.response:
async post(request, env, params) {
this.response.status = 201;
this.response.headers.set('Set-Cookie', 'session=abc123');
return { created: true };
}Or return a Response directly for full control:
async get() {
return new Response('<html>...</html>', {
headers: { 'Content-Type': 'text/html' }
});
}CORS Support
Configure CORS at the router level or per-handler with dynamic control:
// Router-level CORS (applies to all handlers without their own cors())
const router = new WorkerRouter<Env>('api', {
cors: { origins: '*' }
});
// Per-handler dynamic CORS
class ApiHandler extends RouteHandler<Env> {
cors(request: Request, env: Env) {
const origin = request.headers.get('Origin');
// Allow specific subdomains
if (origin?.endsWith('.myapp.com')) {
return { origins: origin, credentials: true };
}
return undefined; // Use router default
}
async get() {
return { data: 'hello' };
}
}CORS headers are automatically consistent between OPTIONS preflight and actual responses.
Middleware Support
Chain middleware for authentication, logging, etc:
router
.all('/api/*', authMiddleware)
.defineRouteHandler('/api/users', UserHandler);Documentation
https://webheroesinc.github.io/js-cf-routing/
API documentation is automatically generated from source code using TypeDoc and deployed on every push to master.
To generate locally:
npm run docs # Generate documentation in docs/
npm run docs:watch # Generate docs in watch modeDevelopment
See CONTRIBUTING.md for development setup, testing, and contribution guidelines.
Running Tests
npm test # Run all tests
npm run test:unit # Unit tests only
npm run test:integration # Integration tests only
npm run test:coverage # With coverage reportBuilding
npm run build # Build TypeScript to lib/
npm run format # Format code with PrettierLicense
LGPL-3.0
Credits
Built on top of itty-router by Kevin Whitley.