routerling
v0.1.1
Published
Routerling is a simple and fast router for Node.js
Readme
Routerling
A simple, fast, and powerful web framework for Node.js with built-in WebSocket support, lifecycle hooks, and daemon processes.
Features
- 🚀 Fast HTTP Routing - Efficient route matching and handling
- 🔌 WebSocket Support - Built-in WebSocket server with route-based handlers
- 🎯 Lifecycle Hooks - STARTUP and SHUTDOWN hooks for initialization and cleanup
- ⚙️ Daemon Processes - Register background tasks that run on server startup
- 📦 Context Object - Store and share values across request handlers and middleware
- 🌐 Subdomain Routing - Route requests based on subdomains
- 📦 Router Mounting - Compose applications from multiple routers
- 🎨 Template Rendering - Built-in Nunjucks template support
- 📁 Static Files - Serve static assets with automatic MIME type detection
- 🍪 Cookie Parsing - Built-in cookie support
- 📤 File Uploads - Handle multipart form data and file uploads
Installation
npm install routerlingQuick Start
import { Router, STARTUP, SHUTDOWN } from 'routerling';
const app = new Router();
// Startup hook - runs when server starts
app.ONCE(STARTUP, async () => {
console.log('Server initializing...');
// Connect to database, load config, etc.
});
// Shutdown hook - runs when server stops
app.ONCE(SHUTDOWN, async () => {
console.log('Cleaning up...');
// Close connections, save state, etc.
});
// HTTP routes - handlers receive (req, res, ctx)
app.GET('/', (req, res, ctx) => {
res.json({ message: 'Hello from Routerling!' });
});
app.POST('/api/users', (req, res, ctx) => {
const user = req.body;
res.status = 201;
res.json({ id: 1, ...user });
});
// WebSocket endpoint
app.WS('/chat', (ws, request) => {
ws.on('message', (data) => {
ws.send(`Echo: ${data}`);
});
});
// Start server
app.listen(3000, 'localhost', () => {
console.log('Server running on http://localhost:3000');
});API Reference
Router Methods
HTTP Methods
GET(route, handler, subdomain?)- Handle GET requestsPOST(route, handler, subdomain?)- Handle POST requestsPUT(route, handler, subdomain?)- Handle PUT requestsPATCH(route, handler, subdomain?)- Handle PATCH requestsDELETE(route, handler, subdomain?)- Handle DELETE requestsHEAD(route, handler, subdomain?)- Handle HEAD requestsOPTIONS(route, handler, subdomain?)- Handle OPTIONS requestsHTTP(route, handler, subdomain?)- Handle all HTTP methods
Route Parameters with Type Coercion:
:id- String parameter (default):id:int- Integer parameter (auto-converted to number):price:float- Float parameter (auto-converted to number):active:bool- Boolean parameter (auto-converted to boolean)
Examples:
app.GET('/users/:id:int', (req, res, ctx) => {
// req.params.id is a number, not a string
console.log(typeof req.params.id); // 'number'
});
app.GET('/products/:id:int/reviews/:rating:float', (req, res, ctx) => {
// Both params are auto-converted to numbers
});WebSocket
WS(route, handler, subdomain?)- Handle WebSocket connections
Lifecycle
ONCE(event, handler)- Register startup/shutdown hooksSTARTUP- Runs when server startsSHUTDOWN- Runs when server stops
Daemons
DAEMON(handler)- Register background process
Middleware
BEFORE(route, handler, subdomain?)- Add before middlewareAFTER(route, handler, subdomain?)- Add after middleware
Wildcard Middleware: Middleware supports wildcard patterns to match multiple routes:
// Matches /api/users, /api/products, etc.
app.BEFORE('/api/*', (req, res, ctx) => {
ctx.startTime = Date.now();
});
app.AFTER('/api/*', (req, res, ctx) => {
console.log(`Request took ${Date.now() - ctx.startTime}ms`);
});Routing
subdomain(name)- Register a subdomainmount(router, isolated?)- Mount another router
Static Assets & Templates
ASSETS(path)- Serve static files from directoryTEMPLATES(path, options?)- Enable template rendering
State Management
keep(key, value)- Store value in global statepeek(key)- Retrieve value from global stateunkeep(key)- Remove and return value from global state
Server
listen(port, hostname, callback?)- Start HTTP serverclose()- Stop server gracefully
Request Object
app.GET('/user/:id', (req, res, ctx) => {
req.params.id // Route parameters
req.query // Query string parameters
req.body // Parsed request body
req.headers // Request headers
req.cookies // Parsed cookies
req.files // Uploaded files
req.method // HTTP method
req.url // Request URL
req.path // URL path
});Response Object
app.GET('/example', (req, res, ctx) => {
res.status = 200; // Set status code
res.body = 'Hello'; // Set response body
res.json({ key: 'value' }); // Send JSON
res.html('<h1>Hello</h1>'); // Send HTML
res.redirect('/other'); // Redirect
res.cookie('name', 'value', opts); // Set cookie
res.header('X-Custom', 'value'); // Set header
});Context Object
The context object allows you to store and retrieve values across request handlers, middleware, and the request lifecycle.
// Store values in context
app.BEFORE('/api/*', (req, res, ctx) => {
ctx.keep('startTime', Date.now());
ctx.user = { id: 1, name: 'John' }; // Proxy syntax
});
app.GET('/api/data', (req, res, ctx) => {
// Retrieve values from context
const user = ctx.user; // Proxy syntax
const startTime = ctx._data.get('startTime');
res.json({ user, processingTime: Date.now() - startTime });
});
// Context methods
ctx.keep(key, value) // Store a value
ctx.has(key) // Check if key exists
ctx.delete(key) // Remove a key
ctx.keys() // Get all keys
ctx.values() // Get all values
ctx.entries() // Get all entries
ctx.clear() // Clear all data
ctx.size // Number of stored valuesExamples
Daemon Process
app.DAEMON(async (router) => {
// Background task that runs on startup
setInterval(() => {
console.log('Health check...');
}, 60000);
});Subdomain Routing
app.subdomain('api');
const handler = (req, res, ctx) => {
res.json({ subdomain: 'api' });
};
app.GET('/users', handler, 'api'); // api.example.com/users
app.GET('/users', handler); // www.example.com/usersRouter Mounting
const apiRouter = new Router();
const getUsers = (req, res, ctx) => res.json({ users: [] });
const createUser = (req, res, ctx) => res.json({ created: true });
apiRouter.GET('/users', getUsers);
apiRouter.POST('/users', createUser);
app.mount(apiRouter);Template Rendering
await app.TEMPLATES('./views');
app.GET('/page', (req, res, ctx) => {
res.render('template.html', { data: 'value' });
});Static Files
await app.ASSETS('./public');
// Serves files from ./public directoryTesting
npm testLicense
MIT
Author
Tersoo Ortserga
