#Using middleware in the DI system to manage dependencies

8 messages · Page 1 of 1 (latest)

obtuse cave
#

Can you export middleware from modules?
Problem: Middleware can have dependencies that are injected. I'd love a way to have those defined in a MiddlewareSpecificModule such that anyone importing that gets the dependencies they need. Instead of what I see today in examples where a Module must inspect all middleware's injections to figure out its imports. It doesn't make middleware quite the abstraction we'd want.
I've played around a bit and haven't found an easy way to do this, maybe something really round about with adding my own elements to DI tree and dynamic modules.

celest dove
#

you can use middlewares just like any other provider

#

for example:

import { Module, MiddlewareConsumer, RequestMethod, Injectable, NestMiddleware } from '@nestjs/common';
import type { Request, Response, NextFunction } from 'express';

class FooProvider {}

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  constructor(private readonly foo: FooProvider) {
    console.log('LoggerMiddleware created');
  }

  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}

@Module({
  providers: [
    FooProvider,
    LoggerMiddleware,
  ],
  exports: [LoggerMiddleware],
})
class MiddlewareModule {}

@Module({
  imports: [MiddlewareModule],
})
export class AppModule {
  constructor(
    private readonly middleware: LoggerMiddleware,
  ) {}

  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(this.middleware.use.bind(this.middleware))
      .forRoutes({ path: '/', method: RequestMethod.GET });
  }
}
#

but that looks hacky

#

personally, I don't like that because to me middlewares should be either generic enough to do not rely on any other provider or be dedicated to each module, instead of shared across modules

obtuse cave
#

yea the bind() is what i was missing, neater then my rabbithole. our use case is prob generalizable: we have a module that manages jwts, and for all controllers in the app we want a jwt guard. instead of every module knowing the jwt dependencies, it should just import JwtModule for the guard.

#

but this won't work for guards i guess just middleware

celest dove
#

yeah
there's no such feature in nestjs