DocumentationRouter Basics

Router Basics & Configuration

Creating a Router

The create() function is the main entry point to Kaito. It creates a new router instance with your configuration and returns it.

import {create} from '@kaito-http/core';
 
const router = create(); // Arguments to `create()` are optional
 
const handle = router.serve();
 
Bun.serve({
	fetch: handle,
	port: 3000,
});

Error Handling

The onError configuration function is called whenever an error is thrown in the request lifecycle. This function should reply with an object that contains a status and message. These will be used to reply to the client.

import {create} from '@kaito-http/core';
import {ZodError} from 'zod';
 
export const router = create({
	onError: async (error, req) => {
		if (error instanceof ZodError) {
			return {status: 400, message: 'Invalid request'};
		}
 
		return {status: 500, message: 'Internal Server Error'};
	},
});

Request Lifecycle

Kaito has a basic lifecycle for transforming/intercepting requests and responses:

  • .before() runs before the router is handled. You can return early here to stop the request from being handled.
  • .transform() runs on EVERY response, including those from .before() and the router itself.

Here’s an example implementing CORS:

const ALLOWED_ORIGINS = ['http://localhost:3000', 'https://app.example.com'];
 
export const router = create({
	getContext,
	before: async req => {
		if (req.method === 'OPTIONS') {
			// Return early to skip the router
			return new Response(null, {status: 204});
		}
	},
 
	transform: async (request, response) => {
		const origin = request.headers.get('origin');
 
		// Include CORS headers if the origin is allowed
		if (origin && ALLOWED_ORIGINS.includes(origin)) {
			response.headers.set('Access-Control-Allow-Origin', origin);
			response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
			response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
			response.headers.set('Access-Control-Max-Age', '86400');
			response.headers.set('Access-Control-Allow-Credentials', 'true');
		}
	},
});
💡

You can return a response inside .transform() as well, but this is less common. Most often you’ll only be mutating headers.