Context
In Kaito, context is information shared to every single route. It’s provided at the root of your application and is generated on every single request.
For example, if you want to provide the req
and res
objects to each route, you should add it to your context.
Below is an example of things that you could include, but it’s really up to you and what you would find useful to include in your app.
In the documentation about routers, you’ll learn about how routers can create their own context, enabling powerful separation of concerns.
It’s important to note that passing the response object is potentially harmful. This is because a developer could misuse it and start overwriting headers or sending data to the client in a way that you didn’t intend. Instead, I’d recommend only passing as few values as needed. If you needed access to cookies, perhaps provide a getCookie(name: string)
method, or something similar. This is by principle of least privilege.
import {createUtilities} from '@kaito-http/core';
// Use the `createUtilities` helper to also create a strongly typed `router` function
export const {getContext, router} = createUtilities(async (req, res) => {
return {
req,
res,
time: new Date(),
searchForUser: async (query: string) => {
return await db.users.search(query);
},
// This is just an example
getSession: async () => {
const cookies = req.headers.cookie;
// this is bad code, use a cookie parser library! npmjs.com/package/cookie is a good one
const token = cookies
?.split(';')
.find(cookie => cookie.startsWith('token='))
.split('=')[1];
return await db.sessions.findByToken(token);
},
};
});
You can then use this context, when setup correctly with a router, inside every single route. E.g.
import {z} from 'zod';
import {router} from './context';
export const users = router().get('/users', {
query: {
search: z.string(),
},
async run({ctx, query}) {
const users = await ctx.searchForUser(query.search);
return users;
},
});