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 it's properties within a Route or Hook. The context is passed to every handler so there should'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 {HeaderHookDef, Routes, registerRoutes} from '@mionkit/router';
import {getAuthUser, isAuthorized} from 'MyAuth';

const authorizationHook = {
    headerName: 'authorization',
    async hook(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
    },
} satisfies HeaderHookDef;

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

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

export const apiSpec = registerRoutes(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

const routes = {getMyPet} satisfies Routes;
initRouter({sharedDataFactory: initSharedData});
export const apiSpec = registerRoutes(routes);

Using a typed shared data in routes and hooks

type MyContext = CallContext<SharedData>;
const getMyPet = async (ctx: MyContext): Promise<Pet> => {
    const user = ctx.shared.myUser;
    const pet = myApp.db.getPetFromUser(user);
    return pet;
};

Type Reference

CallContext

export type CallContext<SharedData = 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;
};