1. 程式人生 > 程式設計 >NestJs學習之旅(5)——中介軟體

NestJs學習之旅(5)——中介軟體

歡迎持續關注NestJs之旅系列文章

二維碼

中介軟體

中介軟體是在路由處理程式之前呼叫的函式。中介軟體函式可以訪問請求響應物件。

使用過koa和express的朋友應該知道,中介軟體是一個很核心的功能,尤其是koa,核心就是中介軟體,連路由功能都是由中介軟體提供的。

中介軟體可以提供以下功能:

  • 執行過程中執行任意程式碼
  • 對請求和響應進行更改
  • 結束本次請求的響應
  • 繼續呼叫下一個中介軟體

示例

NestJs使用@Injectable()來裝飾中介軟體,被裝飾的物件應該實現NestMiddleware介面。

以下是一個日誌中介軟體的實現:

// log.middleware.ts
import {Injectable,NestMiddleware} from
'@nestjs/common'; import {Request,Response} from 'express'; @Injectable() export class LogMiddleware implements NestMiddleware { use(req: Request,resp: Response,next: Function) { console.log(`${req.method} ${req.path}`) next(); } } 複製程式碼
// app.module.ts
import { Module,NestModule,MiddlewareConsumer } from
'@nestjs/common'; import { LogMiddleware } from './common/middleware/log.middleware'; import { UserModule } from './user/user.module'; @Module({ imports: [UserModule],}) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LogMiddleware) .forRoutes('users'
); } } 複製程式碼

針對請求方法應用中介軟體

上面的簡單示例中會對所有的users路由應用中介軟體,如果需要只對特定的請求方法,比如GET請求才應用中介軟體,可以使用以下方式:

import { Module,})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware)
       .forRoutes({ path: 'users',method: RequestMethod.GET });
  }
}
複製程式碼

應用多箇中介軟體

import { Module,})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware,OtherMiddleware)
       .forRoutes({ path: 'users',method: RequestMethod.GET });
  }
}
複製程式碼

基於控制器名稱應用中介軟體

上述程式碼都是針對固定的路由地址應用中介軟體,在NestJs中路由地址是通過裝飾器定義的,如果控制器的路由地址有變化,而中介軟體這裡沒有跟著改掉,就會導致問題。

NestJs在使用中介軟體的時候提供了基於控制器來註冊的方式:

import { Module,})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware)
       .forRoutes(UserController);
  }
}
複製程式碼

排除指定路由

有些場景下對控制器應用了中介軟體之後需要繞過其中幾個方法,比如登入驗證中介軟體應該放行登入路由,否則沒有人能夠登入成功。

import { Module,})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware)
      .exclude(
          {path:'users/login',method:RequestMethod.GET}
      )
       .forRoutes(UserController);
  }
}
複製程式碼

全域性中介軟體

類似於全域性模組,中介軟體也可以全域性註冊,對每一個路由都生效。

// main.ts
const app = await NestFactory.create(AppModule);
app.use(LogMiddleware);
await app.listen(3000);
複製程式碼

結尾

中介軟體給框架賦予了極大的靈活性,可以根據功能抽象為中介軟體,達到”可插拔“的目的。

如果您覺得有所收穫,分享給更多需要的朋友,謝謝!

如果您想交流關於NestJs更多的知識,歡迎加群討論!

image