Route 핸들러 이전에 호출되는 함수
미들웨어 기능은 다음 작업을 수행할 수 있습니다.
- 어떤 코드라도 실행하세요.
- 요청 및 응답 개체를 변경합니다.
- 요청-응답 주기를 종료합니다.
- 스택에서 다음 미들웨어 함수를 호출합니다.
- 현재 미들웨어 기능이 요청-응답 주기를 종료하지 않으면 next()다음 미들웨어 기능으로 제어를 전달하기 위해 호출해야 합니다. 그렇지 않으면 요청이 중단된 상태로 유지됩니다.
@Injectable() 데코레이터로 middleware Function Or Class 생성
NestMiddleware 인터페이스 를 implementsExpress미들웨어를 다르게 처리 하고 fastify다양한 메소드 서명을 제공합니다. 자세한 내용은 여기를 참조하세요 .
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...');
next();
}
}
DI 가능하고,constructor 를 통해 처리
Module 내 configure() 함수를 통해 등록
NestModule 인터페이스를 implementsimport { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('cats');
// 값 제한
.forRoutes({ path: 'cats', method: RequestMethod.GET });
}
}
async/await(예시, "configure()" 함수 내부에서 비동기 작업 처리)를 통해configure()함수가 비동기 함수가 될 수 있습니다.
Express 어댑터 사용 시,
body-parser패키지에서json과urlencoded를 등록합니다.MiddlewareConsumer로 미들웨어를 customize 할 시,NestFactory.create()내bodyParser를false로 설정해 전역 미들웨어 처리를 하지 않아야 합니다.
경로 상 Pattern 지원
forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
fastify패키지는 최신의path-to-regexp패키지를 쓰고 있는데, 이는 더 이상 를 지원하지 않습니다. 대신에, parameters 를 사용해야 합니다(예시, (.) ,:splat*).
MiddlewareConsumer 는 Helper 클래스의 일종으로, 미들웨어를 관리하기 위한 내장 함수 제공
forRoutes() 함수에는 단일-복수 문자열, RouteInfo 객체, 단일-복수 controller class 들어옴import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes(CatsController);
}
}
apply()함수는 단일 미들웨어와 복수 미들웨어를 위한 복수 변수를 인자로 받습니다.
미들웨어가 적용되는 route 를 배제하고 싶을 때, exclude() 함수 사용
RouteInfo 객체 적용consumer
.apply(LoggerMiddleware)
.exclude(
{ path: 'cats', method: RequestMethod.GET },
{ path: 'cats', method: RequestMethod.POST },
'cats/(.*)',
)
.forRoutes(CatsController);
exclude()함수는path-to-regexp패키지에서 지원하는 와일드카드 매개 변수를 지원합니다.
단일 함수 형태로도 적용 가능
import { Request, Response, NextFunction } from 'express';
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
};
consumer
.apply(logger)
.forRoutes(CatsController);
미들웨어에 종속성이 필요하지 않은 경우
함수형 미들웨어를 고려해보세요
순차적으로 적용되는 미들웨어는 단순 comma 로 apply() 함수에 적용 가능
consumer.apply(cors(),helmet(),logger).forRoutes(CatsController);
INestApplication 인스턴스에서 제공하는 use() 함수를 통해 모든 route 에 적용할 수 있음
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
글로벌 미드웨어에서는 DI 컨테이너에 접근할 수 없습니다. 이를 위해
app.use()함수에함수형 미들웨어를 적용할 수 있습니다. 혹은, 클래스 미들웨어를AppModule(혹은 다른 모듈) 에서.forRoutes('*')와 함께 사용할 수 있습니다