middleware
設計 Middleware
Middleware 有兩種設計方式,一般的 function 或 帶有 @Injectable 裝飾器並實作 NestMiddleware 介面的 class:
Functional middleware
這種 Middleware 十分單純,就是一個普通的 function,不過有三個參數,分別是:Request、Response 以及 NextFunction,使用方法與 Express middleware 是一樣的。下方為一個簡單的範例,可以看到在函式的結尾呼叫了 next(),表示將執行下一個執行步驟:
Class middleware
這種 Middleware 可以透過 CLI 產生:
$ nest generate middleware <MIDDLEWARE_NAME>
建立出來的 Middleware 骨架如下,會看到有一個 use(req: any, res: any, next: () => void) 方法,那正是處理邏輯的地方:
import { Injectable, NestMiddleware } from "@nestjs/common";
import { NextFunction, Request, Response } from "express";
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
next();
}
}
在 AppModule 實作 NestModule 與 configure(consumer: MiddlewareConsumer) 方法,並透過 apply 來套用 Middleware,再透過 forRoutes 設置要採用此 Middleware 的路由:
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TodoModule } from "./features/todo/todo.module";
import { LoggerMiddleware } from "./middlewares/logger.middleware";
@Module({
imports: [TodoModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes("/todos");
// consumer.apply(LoggerMiddleware).forRoutes('*'); // 全部的 router 都要 ~
}
}