The handler

The createKaitoHandler function is a very minimal part of Kaito, it simply wraps all your functions together and returns a request -> response function.

import {createKaitoHandler} from '@kaito-http/core';
 
const handler = createKaitoHandler({
	getContext,
	router,
	onError,
});
 
Bun.serve({fetch: handler, port: 3000});

onError

In the example above, you can see I have included a property called onError. This is a function that 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 {createKaitoHandler} from '@kaito-http/core';
import {ZodError} from 'zod';
 
const handler = createKaitoHandler({
	// Be careful with using `res` here.
	onError: async ({error, req, res}) => {
		if (error instanceof ZodError) {
			return {status: 400, message: 'Invalid request'};
		}
 
		return {status: 500, message: 'Internal Server Error'};
	},
	// ...
});

Before/Transform

Kaito has a basic lifecycle for transform/intercepting requests and responses. The most common use case is to add CORS headers.

  • .before() runs before the router is handled. You can return early here to stop the request from being handled by the router.
  • .transform() runs on EVERY response. That includes ones from .before() and ones from the router.
const ALLOWED_ORIGINS = ['http://localhost:3000', 'https://app.example.com'];
 
const server = createKaitoHandler({
	getContext,
	router,
 
	before: async req => {
		if (req.method === 'OPTIONS') {
			return new Response(null, {status: 204}); // Return early to skip the router. This response will be passed to `.transform()`
		}
	},
 
	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, 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');
		}
	},
});

This feature was called Before/After in Kaito v2. The functionality has changed a little bit, so migrating to v3 might require some changes.