opl- / koa-butterfly

🦋 Butterfly is a feature packed Koa router

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add Router proxy with enforced prefix

opl- opened this issue · comments

commented

A common pattern for me appears to be creating a new Router instance to create a "namespace" of routes. For example, I might create a new Router for all paths starting with /api/user/:userId, on which I will register all endpoints which relate to a specific user: /activity, /posts, /ban (all with the implicit /api/user/:userId prefix). This is done to avoid repetition, and reduce potential for typos or incomplete refactors.

This does work, but makes it more difficult to register middleware (see #1), makes debugging more difficult and possibly increases overhead (the route processing goes through multiple Router handlers), and, if the routes are registered in a different file, makes it more difficult to immediately see what the path prefix is.

A possible pattern to improve this is to introduce a proxy Router, which will always prefix all registered paths with a set prefix.

Exposing this as a Router method would also create a convenient way to expand the context types for all the routes declared under it, for example to introduce the userId param, or a resolved User instance in the state.

const apiRouter = new Router();

interface UserRouterContext {
    params: {
        userId: string;
    };

    state: {
        user: User;
    };
}

// TODO: Function name to be determined (prefix, namespace?).
const userPrefix = apiRouter.createPrefix<{}, UserRouterContext>('/api/user/:userId');

userPrefix.use('/*', async (ctx, next) => {
    const user = await User.byId(ctx.params.userId);
    if (!user) {
        ctx.status = 404;
        return;
    }

    ctx.user = user;

    await next();
});