'NestJS Middleware Not Executed
The NestJS class or functional middleware doesn't run when connected from a Module. It is also not working for a single path, controller or for every path. Connecting functional middleware from main.ts works fine.
//main.ts
import { ValidationPipe } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'
import { AppModule } from './app.module'
declare const module: any
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter())
app.useGlobalPipes(new ValidationPipe())
await app.listen(2100)
if (module.hot) {
module.hot.accept()
module.hot.dispose(() => app.close())
}
}
bootstrap()
//app.module.ts
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'
import { AuthMiddleware } from './middleware/auth.middleware'
import { UserModule } from './user/user.module'
@Module({
imports: [UserModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(AuthMiddleware)
.forRoutes('(.*)')
}
}
//auth.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common'
import { FastifyRequest, FastifyReply } from 'fastify'
@Injectable()
export class AuthMiddleware implements NestMiddleware {
use(req: FastifyRequest, res: FastifyReply, next: () => void) {
console.log('test auth middleware')
next()
}
}
Expected output: test auth middleware
Actual: nothing
Solution 1:[1]
The problem was installing the "fastify" package along with "@nestjs/platform-fastify". In addition, if you remove the "fastify" package, then the dependencies used in the "@nestjs/platform-fastify" package are also removed, so it won't work correctly. If you've installed both packages, uninstall "fastify" and reinstall "@nestjs/platform-fastify".
Solution 2:[2]
I'm not using Fastify but my middleware wasnt executing even taken straight from the docs. I built my project (npm run build
) then went back to dev mode npm run start:dev
and that seemed to work. When in doubt investigate the /dist
directory.
Solution 3:[3]
I have the same problem. Works just fine when using an explicit controller, but not with '*'. Also tried:
forRoutes({path: '*', method: RequestMethod.ALL })
but that doesn't seem to work either. My solution was, unfortunately, using a global functional middleware, as the example here shows. This is not not very maintainable, since it is defined in main.ts and not in app.module. This caused some problems with e2e testing, but I was able to make it work, eventually. Just make sure to use the middleware in main.ts and when creating a test module for e2e tests.
main.ts:
const app = await NestFactory.create(AppModule);
app.use(functionalMiddleware);
in your e2e test module:
const createAppE2e = async (): Promise<INestApplication> => {
const moduleRef = await Test.createTestingModule({
imports: [AppModule],
});
const app = moduleRef.createNestApplication();
app.use(functionalMiddleware);
await app.init();
return app;
}
Solution 4:[4]
In my case, I wanted to apply one middleware globally, and one middleware at a specific module level. But For some reason, middleware doesn't work when you apply it at a specific module level.
export class PartnerModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(ModuleSpecificMiddleware);
}
}
So I found another way to do it. At app module you can assign it like this.
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(AuthMiddleware);
consumer.apply(ModuleSpecificMiddleware).forRoutes(PartnerController); // This was the solution
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Roman Sivtsov |
Solution 2 | Zenkylo |
Solution 3 | |
Solution 4 | Subham kuswa |