iT邦幫忙

2024 iThome 鐵人賽

DAY 6
1

nestjs 分層元件 Middleware

目標

  1. 介紹 nestjs 分層架構概念
  2. 介紹 nestjs 分層元件 Middleware

概念

前面介紹了 nestjs 三種基礎的元件, Module, Provider 與 Controller。可以處理簡單的後端 api 功能。

nestjs 對於 request flow 提供了更細部的分層元件,來讓整個 request flow 的職責可以切分的更細緻。讓開發者可以把不同關注點的邏輯做隔離。使得該元件只會修改只會與其職責相關,儘可能做到單一職責原則。

這篇會從 Middleware 開始介紹。

nestjs request flow 分層架構圖


ref linkedin slide

這邊的分層架構是以 http request 整個生命周期來做橫切。 request 從進入 nestjs 應用依序會從 Middleware , Guard , Interceptor , Pipe , Controller 傳入找到對應的 service 執行。執行結果,會從依序從 Controller, Interceptor , Exception Filter(如果有 Exception 的話) 傳出。

nestjs Middleware 元件

Middleware 是 http request 的處理最外一關,可以用添加資料到 request 或是 response。比如透過 request header cookie 的 session id 查出對應的 session 資料放入 execution context 讓後許的處理可以沿用資料。或是根據某些結果在 response header 做一些設置。另外,也可以用來做簡單的 log 功能,紀錄每次 request 資料的執行時間 ,與回應的 http code 。

語法

  1. 實作內建的 NestMiddleware
  2. 宣告 @Injectable() 裝飾子方便注入其他功能
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();
  }
}

  1. 在要使用的 module
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './middleware/logger.middleware';
@Module({
  imports: [],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('*');
  }
}

可以注意到 middleware 的影響範圍基本上可以設定哪些 route 被使用,另外也可以使用排除法,排除不需要的 route 。

全域的 middleware

在 main.ts 中,本身透過 nestjs Factory 產生出來的 app,本身屬於 INestApplication 。具有跟 expressjs 的 app 一樣功能,可以透過 app.use 來套用 Middleware 功能。 所以如果是一個全域的 Middleware,可以透過這種方式使用入如下:

onst app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);

範例

authentication.middleware.ts

import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
import { RequestService } from '../request.service';

@Injectable()
export class AuthenticationMiddleware implements NestMiddleware {
  private readonly logger = new Logger(AuthenticationMiddleware.name);
  constructor(private readonly requestService: RequestService) {}
  use(req: Request, res: Response, next: NextFunction) {
    this.logger.log(AuthenticationMiddleware.name);
    // Authenticate the request
    const userId = '123';
    this.requestService.setUserId(userId);
    next();
  }
}

app.module.ts

import { MiddlewareConsumer, NestModule } from '@nestjs/common';
import { AuthenticationMiddleware } from './middleware/authentication.middleware';
import { RequestService } from './request.service';
@Module({
  providers: [
    RequestService,
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(AuthenticationMiddleware).forRoutes('*');
  }
}

結論

nestjs 的 Middleware 元件提供一個可以把對 http request 與回應做處理的元件。最常用來實作身份驗證的 session 處理,或是做 log 稽核。妥善地利用這個元件有助於把共用邏輯做的良好隔離。


上一篇
nestjs 核心元件 Controller
下一篇
nestjs 分層元件 Guard
系列文
透過 nestjs 框架,讓 nodejs 系統維護度增加31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
0
雷N
iT邦研究生 1 級 ‧ 2024-09-06 11:50:55

看不懂 那也沒關係 白話一點就是兩個字 遠見

先談鄭河嚇西朗

我要留言

立即登入留言