UNPKG

7.15 kBMarkdownView Raw
1# Worker Router
2A router for [Worker Runtimes](https://workers.js.org) such as Cloudflare Workers and Service Workers.
3
4This router is inspired by previous work, specifically `tiny-request-router` and `itty-router`, but it
5improves on them by providing better support for middleware, type inference, nested routing, and broader URL matching for use in service workers.
6
7## πŸ†“ Type Inference
8The goal of Worker Router is to *infer types based on usage* so that **no explicit typing** is required for standard use cases.
9This allows even JavaScript users to benefit from inline documentation and API discoverability. For example,
10
11```js
12const router = new WorkersRouter()
13 .get('/about', basics(), (req, { userAgent }) => ok())
14 .get('/login', unsignedCookies(), (req, { cookies }) => ok())
15```
16
17In this example your editor can infer the types and documentation for
18 - `userAgent`, provided by the `basics` middleware
19 - `cookies`, provided by the `unsignedCookies` middleware
20
21
22## πŸ”‹ Functional Middleware
23Worker Router [middlewares](https://workers.tools/middleware) are *just function* that add properties to a generic context object.
24As such, they can be *mixed and matched* using standard tools from functional programming.
25
26For convenience, this module provides a `combine` utility to combine multiple middlewares into one.
27
28```js
29const myReusableMW = combine(
30 basics(),
31 signedCookies({ secret: 'password123' }),
32 cookieSession({ user: '' })
33);
34
35const router = new WorkersRouter()
36 .get('/', myReusableMW, () => ok())
37 .post('/', combine(myReusableMW, bodyParser()), () => ok())
38```
39
40Note that type inference is maintained when combining middleware!
41
42
43## πŸͺ† Nested Routing
44Worker Router supports delegating entire sub routes to another router:
45
46```js
47const itemRouter = new WorkerRouter()
48 .get('/', (req, { params }) => ok(`Matched "/item/`))
49 .get('/:id', (req, { params }) => ok(`Matched "/item/${params.id}`))
50
51const router = new WorkersRouter()
52 .get('/', () => ok('Main Page'))
53 .use('/item*', itemRouter)
54```
55
56
57## βš™οΈ Ready for Service... Worker
58Internally, this router uses [`URLPattern`](https://web.dev/urlpattern/) for routing, which allows it match URLs in the broadest sense.
59For example, the following router, meant to be used in a Service Worker, can handle internal requests as well as intercept calls to external resources:
60
61```js
62// file: "sw.js"
63const router = new WorkersRouter()
64 .get('/', () => ok('Main Page'))
65 .get('/about', () => ok('About Page'))
66 .external('https://plausible.io/api/*', req => {
67 // intercepted
68 })
69```
70
71## πŸ’₯ Error Handling Without Even Trying
72Worker Router has first class support for error handling. Its main purpose is to let you write your handlers without having to wrap everything inside a massive `try {} catch` block. Instead, you can define special recover routes that get invoked when something goes wrong.
73
74```js
75const router = new WorkersRouter()
76 .get('/', () => ok('Main Page'))
77 .get('/about', () => { throw Error('bang') })
78 .recover('*', (req, { error, response }) =>
79 new Response(`Something went wrong: ${error.message}`, response)
80 );
81```
82
83## βœ… Works with Workers
84Worker Router comes with out of the box support for a variety of Worker Runtimes:
85
86To use it in an environment that provides a global `fetch` event, use
87
88```js
89self.addEventListener('fetch', router)
90```
91
92(This works because the router implements the [`EventListener`](https://developer.mozilla.org/en-US/docs/Web/API/EventListener) interface)
93
94To use it with Cloudflare's module workers, use
95
96```js
97export default router
98```
99
100(This works because the router implements a `fetch` method with compatible interface)
101
102To use it with Deno/Deploy's `serve` function, use
103
104```js
105serve(router.serveCallback)
106```
107
108<!-- While Worker Router is influenced by earlier work, it is __not in the tradition__ of express, koa and other modify-in-place routers, save for aspects of its high level API.
109At it's core, Worker Router is a function of `(req: Request, ctx: Context) => Promise<Response>`. In this model,
110middleware is another function that *adds* properties to the context, which is fully tracked by the type system. Conversely, middleware that is not applied is also absent and not polluting the context object. -->
111
112<br/>
113
114--------
115
116<br/>
117
118<p align="center"><a href="https://workers.tools"><img src="https://workers.tools/assets/img/logo.svg" width="100" height="100" /></a>
119<p align="center">This module is part of the Worker Tools collection<br/>⁕
120
121[Worker Tools](https://workers.tools) are a collection of TypeScript libraries for writing web servers in [Worker Runtimes](https://workers.js.org) such as Cloudflare Workers, Deno Deploy and Service Workers in the browser.
122
123If you liked this module, you might also like:
124
125- 🧭 [__Worker Router__][router] --- Complete routing solution that works across CF Workers, Deno and Service Workers
126- πŸ”‹ [__Worker Middleware__][middleware] --- A suite of standalone HTTP server-side middleware with TypeScript support
127- πŸ“„ [__Worker HTML__][html] --- HTML templating and streaming response library
128- πŸ“¦ [__Storage Area__][kv-storage] --- Key-value store abstraction across [Cloudflare KV][cloudflare-kv-storage], [Deno][deno-kv-storage] and browsers.
129- πŸ†— [__Response Creators__][response-creators] --- Factory functions for responses with pre-filled status and status text
130- 🎏 [__Stream Response__][stream-response] --- Use async generators to build streaming responses for SSE, etc...
131- πŸ₯ [__JSON Fetch__][json-fetch] --- Drop-in replacements for Fetch API classes with first class support for JSON.
132- πŸ¦‘ [__JSON Stream__][json-stream] --- Streaming JSON parser/stingifier with first class support for web streams.
133
134Worker Tools also includes a number of polyfills that help bridge the gap between Worker Runtimes:
135- ✏️ [__HTML Rewriter__][html-rewriter] --- Cloudflare's HTML Rewriter for use in Deno, browsers, etc...
136- πŸ“ [__Location Polyfill__][location-polyfill] --- A `Location` polyfill for Cloudflare Workers.
137- πŸ¦• [__Deno Fetch Event Adapter__][deno-fetch-event-adapter] --- Dispatches global `fetch` events using Deno’s native HTTP server.
138
139[router]: https://workers.tools/router
140[middleware]: https://workers.tools/middleware
141[html]: https://workers.tools/html
142[kv-storage]: https://workers.tools/kv-storage
143[cloudflare-kv-storage]: https://workers.tools/cloudflare-kv-storage
144[deno-kv-storage]: https://workers.tools/deno-kv-storage
145[kv-storage-polyfill]: https://workers.tools/kv-storage-polyfill
146[response-creators]: https://workers.tools/response-creators
147[stream-response]: https://workers.tools/stream-response
148[json-fetch]: https://workers.tools/json-fetch
149[json-stream]: https://workers.tools/json-stream
150[request-cookie-store]: https://workers.tools/request-cookie-store
151[extendable-promise]: https://workers.tools/extendable-promise
152[html-rewriter]: https://workers.tools/html-rewriter
153[location-polyfill]: https://workers.tools/location-polyfill
154[deno-fetch-event-adapter]: https://workers.tools/deno-fetch-event-adapter
155
156Fore more visit [workers.tools](https://workers.tools).
\No newline at end of file