Search code examples
node.jsmiddlewarekoakoa-router

Node Koa How do I pass a param into middleware?


Converting my Express app to Koa...

I'm googling and I'm googling, I can't find how to pass extra params into Koa middleware. For example...

router.post('/', compose([
    Midware.verifyAuthToken, 
    Midware.bodySchemaTest(UserController.bodyAttribs),
    Midware.injectionTest
]), UserController.postNew);

I need send some variable bodyAttribs (string array) names into the bodySchemaTest middleware and I don't know how to do this in Koa.

I'm just now trying Koa. Please share your expertise :-)


Solution

  • Ok I worked it out myself. Not sure if this is smart or the "right" way to do this but the solution for me was to create a piece of middleware in each controller that sets expected schema attribs in ctx.state.bodyAttribs.

    Like this...

    // /src/routers/user.router.ts
    
    import * as UserController from '../controller/user.controller';
    import * as Midware from './middleware';
    import Router from 'koa-router';
    import compose from 'koa-compose';
    
    const router = new Router();
    router.prefix('/user');
    
    router.get('/', Midware.verifyAuthToken, UserController.getAll);
    
    router.post('/', compose([
        UserController.bodyAttribs,
        Midware.verifyAuthToken,
        Midware.bodySchemaTest,
        Midware.injectionTest,
    ]), UserController.postNew);
    
    module.exports = router;
    
    
    // /src/controller/user.controller.ts 
    
    import { Context } from 'koa';
    import { UserData } from '../data/mongo/user.data.mongo';
    import { UserModel } from '../model/user.model';
    import { EmailValidate } from '../service/email-validate.service';
    import * as Logger from '../util/logger';
    
    const dataContext = new UserData();
    
    // Middleware to set bodyAttribs
    export const bodyAttribs = async (ctx: Context, next: any) => {
        ctx.state.bodyAttribs = ['handle', 'processUserOptions', 'name', 'email', 'pass', 'passConfirm'];
        return await next();
    };
    ...
    

    So each controller provides the custom middleware that set the custom bodyAttribs I want to verify. You can use this approach to set and pass 1 to any number of extra params, whatever you need, in ctx.state which always goes on to next middleware in chain. Follow? :-)