Call Context

The CallContext contains all the data related to the ongoing call.

Most of the data within the CallContext is marked as read-only, this is because it is not recommended to modify the context manually. It is still possible to modify it (the context is not a real Immutable JS object).

Quick Tip:
To avoid memory leak issues you should never store a reference to the context or any of its properties within a Route or Hook. The context is passed to every handler so there shouldn't be any reason to do so.

Sharing Data between Hooks and Routes

To share data between hooks and routes use the shared object within the Call Context.

import {RpcError} from '@mionkit/core';
import {Routes, initMionRouter, headersHook, route} from '@mionkit/router';
import {getAuthUser, isAuthorized} from 'MyAuth';

const authorizationHook = headersHook('authorization', async (context, token: string): Promise<void> => {
    const me = await getAuthUser(token);
    if (!isAuthorized(me)) {
        throw new RpcError({statusCode: 401, publicMessage: 'user is not authorized'});
    }
    context.shared.myUser = me; // user is added to ctx to shared with other routes/hooks
});

const sayMyName = route((context): string => {
    return `hello ${context.shared.myUser.name}`;
});

const routes = {
    authorizationHook,
    sayMyName,
} satisfies Routes;

export const apiSpec = initMionRouter(routes);

Shared Data Factory

It is possible to define a sharedDataFactory function used to initialize the shared data object. This factory function will be called before any route or hook gets executed and the returned value will be the default shared object for all routes and hooks.

Defining a shared data factory

interface SharedData {
    myUser: User | null;
    // ... other shared data properties
}
const initSharedData = (): SharedData => ({myUser: null});

Initializing router with a shared data factory

export const myApi = initMionRouter(routes, {sharedDataFactory: initSharedData});

Using typed shared data in routes and hooks

const routes = {
    getMyPet: route(async (ctx: MyContext): Promise<Pet> => {
        const user = ctx.shared.myUser;
        const pet = await myApp.db.getPetFromUser(user);
        return pet;
    }),
} satisfies Routes;

Type Reference

CallContext

export interface CallContext<SharedData extends Record<string, any> = any> {
    /** Route's path after internal transformation */
    readonly path: string;
    /** Router's own request object */
    readonly request: MionRequest;
    /** Router's own response object */
    readonly response: MionResponse;
    /** shared data between handlers (route/hooks) and that is not returned in the response. */
    shared: SharedData;
}