Package Exports
- @tsndr/cloudflare-worker-router
- @tsndr/cloudflare-worker-router/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 (@tsndr/cloudflare-worker-router) 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 Router
Cloudflare Workers Router is a super lightweight router (1.3K gzipped) with middleware support and ZERO dependencies for Cloudflare Workers.
When I was trying out Cloudflare Workers I almost immediately noticed how fast it was compared to other serverless offerings. So I wanted to build a full-fledged API to see how it performs doing real work, but since I wasn't able to find a router that suited my needs I created my own.
I worked a lot with Express.js in the past and really enjoyed their middleware approach, but since none of the available Cloudflare Worker routers offered middleware support at the time, I felt the need to create this router.
Contents
Features
- ZERO dependencies
- Lightweight (1.3K gzipped)
- Fully written in TypeScript
- Integrated Debug-Mode & CORS helper
- Built specifically around Middlewares
Usage
TypeScript Example
import { Router } from '@tsndr/cloudflare-worker-router'
export interface Env {
// Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
// MY_KV_NAMESPACE: KVNamespace
//
// Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
// MY_DURABLE_OBJECT: DurableObjectNamespace
//
// Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
// MY_BUCKET: R2Bucket
}
// Initialize router
const router = new Router<Env>()
// Enabling build in CORS support
router.cors()
// Register global middleware
router.use(({ req, res, next }) => {
res.headers.set('X-Global-Middlewares', 'true')
next()
})
// Simple get
router.get('/user', ({ req, res }) => {
res.body = {
data: {
id: 1,
name: 'John Doe'
}
}
})
// Post route with url parameter
router.post('/user/:id', ({ req, res }) => {
const userId = req.params.id
// Do stuff...
if (errorDoingStuff) {
res.status = 400
res.body = {
error: 'User did stupid stuff!'
}
return
}
res.status = 204
})
// Delete route using a middleware
router.delete('/user/:id', ({ req, res, next }) => {
if (!apiTokenIsCorrect) {
res.status = 401
return
}
await next()
}, (req, res) => {
const userId = req.params.id
// Do stuff...
})
// Listen Cloudflare Workers Fetch Event
export default {
async fetch(request: Request, env: Env): Promise<Response> {
return router.handle(env, request)
}
}JavaScript Example
import { Router } from '@tsndr/cloudflare-worker-router'
// Initialize router
const router = new Router()
// Enabling build in CORS support
router.cors()
// Register global middleware
router.use(({ req, res, next }) => {
res.headers.set('X-Global-Middlewares', 'true')
next()
})
// Simple get
router.get('/user', ({ req, res }) => {
res.body = {
data: {
id: 1,
name: 'John Doe'
}
}
})
// Post route with url parameter
router.post('/user/:id', ({ req, res }) => {
const userId = req.params.id
// Do stuff...
if (errorDoingStuff) {
res.status = 400
res.body = {
error: 'User did stupid stuff!'
}
return
}
res.status = 204
})
// Delete route using a middleware
router.delete('/user/:id', ({ req, res, next }) => {
if (!apiTokenIsCorrect) {
res.status = 401
return
}
await next()
}, (req, res) => {
const userId = req.params.id
// Do stuff...
})
// Listen Cloudflare Workers Fetch Event
export default {
async fetch(request, env) {
return router.handle(env, request)
}
}Reference
router.debug([state = true])
Enable or disable debug mode. Which will return the error.stack in case of an exception instead of and empty 500 response. Debug mode is disabled by default.
state
State is a boolean which determines if debug mode should be enabled or not (default: true)
| Key | Type | Default Value |
|---|---|---|
state |
boolean |
true |
router.use([...handlers])
Register a global middleware handler.
handler(ctx)
Handler is a function which will be called for every request.
ctx
Object containing env, req, res, next
router.cors([config])
If enabled will overwrite other OPTIONS requests.
config (object, optional)
| Key | Type | Default Value |
|---|---|---|
allowOrigin |
string |
* |
allowMethods |
string |
* |
allowHeaders |
string |
* |
maxAge |
integer |
86400 |
optionsSuccessStatus |
integer |
204 |
Supported Methods
router.any(url, [...handlers])router.connect(url, [...handlers])router.delete(url, [...handlers])router.get(url, [...handlers])router.head(url, [...handlers])router.options(url, [...handlers])router.patch(url, [...handlers])router.post(url, [...handlers])router.put(url, [...handlers])router.trace(url, [...handlers])
url (string)
The URL starting with a /.
Supports the use of dynamic parameters, prefixed with a : (i.e. /user/:userId/edit) which will be available through the req-Object (i.e. req.params.userId).
handlers (function, optional)
An unlimited number of functions getting req and res passed into them.
ctx-Object
| Key | Type | Description |
|---|---|---|
env |
object |
Environment |
req |
req-Object |
Request Object |
res |
res-Object |
Response Object |
next |
next-Handler |
Next Handler |
req-Object
| Key | Type | Description |
|---|---|---|
body |
object / string |
Only available if method is POST, PUT, PATCH or DELETE. Contains either the received body string or a parsed object if valid JSON was sent. |
headers |
Headers |
Request Headers Object |
method |
string |
HTTP request method |
params |
object |
Object containing all parameters defined in the url string |
query |
object |
Object containing all query parameters |
res-Object
| Key | Type | Description |
|---|---|---|
body |
object / string |
Either set an object (will be converted to JSON) or a string |
headers |
Headers |
Response Headers Object |
status |
integer |
Return status code (default: 204) |
webSocket |
WebSocket |
Upgraded websocket connection |
Setup
Please follow Cloudflare's Get started guide to install wrangler.
Initialize Project
wrangler init <name>Use of TypeScript is strongly encouraged :)
npm i -D @tsndr/cloudflare-worker-routerTypeScript (src/index.ts)
import { Router } from '@tsndr/cloudflare-worker-router'
export interface Env {
// Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
// MY_KV_NAMESPACE: KVNamespace
//
// Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
// MY_DURABLE_OBJECT: DurableObjectNamespace
//
// Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
// MY_BUCKET: R2Bucket
}
const router = new Router<Env>()
/// Example Route
//
// router.get(/'hi', ({ res }) => {
// res.body = 'Hello World'
//}
/// Example Route for splitting into multiple files
//
// const hiHandler: RouteHandler<Env> = ({ res }) => {
// res.body = 'Hello World'
// }
//
// router.get('/hi', hiHandler)
// TODO: add your routes here
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
return router.handle(env, request)
}
}JavaScript (src/index.js)
Consider using TypeScript instead :)
import { Router } from '@tsndr/cloudflare-worker-router'
const router = new Router()
// router.get(/'hi', ({ res }) => {
// res.body = 'Hello World'
//}
// TODO: add your routes here
export default {
async fetch(request, env, ctx) {
return router.handle(env, request)
}
}