Features
- Super lightweight
- First-class TypeScript support
- Custom Middleware Support
- Well-organized submodules for à la carte functionality*
- Includes Router with support for pattern definitions
- Familiar Request-Response handler API
- Supports
async
/await
handlers - Fully treeshakable
*More to come!
Install
$ npm install --save worktop
Usage
Check out
/examples
for a list of working demos!
import { Router } from 'worktop';
import * as Cache from 'worktop/cache';
import { uid as toUID } from 'worktop/utils';
import { read, write } from 'worktop/kv';
import type { KV } from 'worktop/kv';
declare var DATA: KV.Namespace;
interface Message {
id: string;
text: string;
// ...
}
// Initialize
const API = new Router();
API.add('GET', '/messages/:id', async (req, res) => {
// Pre-parsed `req.params` object
const key = `messages::${req.params.id}`;
// Assumes JSON (can override)
const message = await read<Message>(DATA, key);
// Alter response headers directly
res.setHeader('Cache-Control', 'public, max-age=60');
// Smart `res.send()` helper
// ~> automatically stringifies JSON objects
// ~> auto-sets `Content-Type` & `Content-Length` headers
res.send(200, message);
});
API.add('POST', '/messages', async (req, res) => {
try {
// Smart `req.body` helper
// ~> parses JSON header as JSON
// ~> parses form-like header as FormData, ...etc
var input = await req.body<Message>();
} catch (err) {
return res.send(400, 'Error parsing request body');
}
if (!input || !input.text.trim()) {
return res.send(422, { text: 'required' });
}
const value: Message = {
id: toUID(16),
text: input.text.trim(),
// ...
};
// Assumes JSON (can override)
const key = `messages::${value.id}`;
const success = await write<Message>(DATA, key, value);
// ^ boolean
// Alias for `event.waitUntil`
// ~> queues background task (does NOT delay response)
req.extend(
fetch('https://.../logs', {
method: 'POST',
headers: { 'content-type': 'application/json '},
body: JSON.stringify({ success, value })
})
);
if (success) res.send(201, value);
else res.send(500, 'Error creating record');
});
API.add('GET', '/alive', (req, res) => {
res.end('OK'); // Node.js-like `res.end`
});
// Attach "fetch" event handler
// ~> use `Cache` for request-matching, when permitted
// ~> store Response in `Cache`, when permitted
Cache.listen(API.run);
API
worktop
Module: The main module – concerned with routing.
This is core of most applications. Exports the Router
class.
worktop/kv
Module: The worktop/kv
submodule contains all classes and utilities related to Workers KV.
worktop/cache
Module: The worktop/cache
submodule contains all utilities related to Cloudflare's Cache.
worktop/request
Module: The worktop/request
submodule contains the ServerRequest
class, which provides an interface similar to the request instance(s) found in most other Node.js frameworks.
Note: This module is used internally and will (very likely) never be imported by your application.
worktop/response
Module: The worktop/response
submodule contains the ServerResponse
class, which provides an interface similar to the IncomingMessage
(aka, "response") object that Node.js provides.
Note: This module is used internally and will (very likely) never be imported by your application.
worktop/base64
Module: The worktop/base64
submodule contains a few utilities related to the Base 64 encoding.
worktop/cookie
Module: The worktop/cookie
submodule contains parse
and stringify
utilities for dealing with cookie header(s).
worktop/cors
Module: The worktop/cors
submodule offers utilities for dealing with Cross-Origin Resource Sharing (CORS) headers.
worktop/crypto
Module: The worktop/crypto
submodule is a collection of cryptographic functionalities.
worktop/utils
Module: The worktop/utils
submodule is a collection of standalone, general-purpose utilities that you may find useful. These may include – but are not limited to – hashing functions and unique identifier generators.
worktop/ws
Module: The worktop/ws
submodule contains the WebSocket
and WebSocketPair
class definitions, as well as two middleware handlers for validating and/or setting up a SocketHandler
for the WebSocket connection.
License
MIT © Luke Edwards