Routes (Remote Methods)

mion has an RPC style routing system so Routes are just functions that can be called remotely.

The first parameter of the remote method is always the Call Context. The rest of parameters are the remote parameters that get deserialized and validated before the route gets executed

There are no URLs or Paths when defining a route, instead the API is defined using a plain javascript object, where every entry of the object is a route or hook. This way we simplify referencing remote methods when calling them from the client.

Internally an URL is generated for each route so these can be referenced using regular http requests, but all this complexity is managed transparently by the client.

Defining a Route

Routes can be defined using the route function by passing the Handler as first parameter and RouteOptions as second.

Quick Tip:
Never assign a type to Routes/Hooks, instead always use the satisfies operator! .
import {RouteOptions, Routes, route} from '@mionkit/router';

const routes = {
    // Using the route function to define a route
    sayHello: route(
        (ctx, name1: string, name2: string): string => {
            return `Hello ${name1} and ${name2}.`;
        },
        {description: 'A route that says hello.'} as RouteOptions
    ),
} satisfies Routes;

Registering Routes

We can register router by passing the routes to initMionRouter or explicitly calling registerRoutes once router has been initialized.

import {AnyObject} from '@mionkit/core';
import {initMionRouter, Routes, CallContext, registerRoutes, route, headersHook} from '@mionkit/router';
import {IncomingMessage} from 'http';

export type HttpRequest = IncomingMessage & {body: string};
export type Shared = () => AnyObject;
export type Context = CallContext<Shared>;

const authRoutes = {
    logIn: route((c, email: string, password: string): string => 'loggedIn'),
    logOut: route((): string => 'loggedOut'),
} satisfies Routes;

const routes = {
    auth: headersHook('Authorization', (c: Context, token: string): null => null),
    sayHello: route((c, name: string): string => 'hello' + name),
    sayHello2: route((c, name: string): string => 'hello' + name),
} satisfies Routes;

export const mayApi = initMionRouter(routes);
export const authApi = registerRoutes(authRoutes);

// export api types to be consumed by the clients
export type MyApi = typeof mayApi;
export type AuthApi = typeof authApi;

Naming Routes

keep it simple and use regular valid JS variable names for routes, It is not recommended to use the array notation (using quotes) to define route names.

When a route lookup is done there is no URL decoding done so if you define names that include especial URl encoded characters then routes won't be found.
import {Routes, route} from '@mionkit/router';

const sayHello = route((ctx, name: string): string => {
    return `Hello ${name}.`;
});

const routes = {
    'say-Hello': sayHello, // path = /say-Hello  !! NOT Recommended
    'say Hello': sayHello, // path = /say%20Hello  !! ROUTE WONT BE FOUND
} satisfies Routes;

Type Reference

Handler

A Route can be a simple function Handler with the call context as first parameter.

export type Handler<Context extends CallContext = any, Ret = any, Params extends any[] = any> = (
    /** Call Context */
    context: Context,
    /** Remote Call parameters */
    ...parameters: Params
) => Ret | Promise<Ret>;

RouteDef

We can use a RouteDef object when we want to customize the default behavior of a route.

/** Route definition */
export type RouteDef<H extends Handler = any> = Pick<RouteProcedure<H>, 'type' | 'handler' | 'canReturnData' | 'runOnError'>;