在NestJS中實現基於請求頭的版本檢測——使用攔截器實現
- 1220字
- 6分鐘
- 2024-09-14
在最近的一個項目中,我們需要為API添加版本控制功能,以確保不同版本的客戶端能夠兼容接口變化,同時在需要時向舊版客戶端提示更新。這種需求在移動端開發中很常見,通常客戶端會通過HTTP請求的header發送當前版本號,服務器再根據版本號返回相應的響應數據。
我們遇到的問題是,在某些情況下,當客戶端版本過舊時,我們希望能夠在正常的返回數據中附加一些更新提示信息,這樣能在接口請求端統一處理該邏輯,而不需要改動原有的業務邏輯。為了解決這一問題,我們可以選擇在NestJS中使用攔截器或者中間件來實現。
本文以攔截器為例,帶大家實現一遍該需求。對於中間件的實現,可以參考這篇文章:《在NestJS中實現基於請求頭的版本檢測——使用中間件實現》
需求分析
需求很簡單:在每個請求的header中攜帶客戶端版本號,服務器根據這個版本號進行檢測。如果客戶端的版本低於服務器要求的最新版本,就需要在響應中附加一個更新提示字段;如果版本符合要求,則正常返回數據而不做修改。
如何實現
在NestJS中,我們可以通過攔截器來捕獲請求和響應。在攔截器中,我們可以:
- 獲取請求頭中的版本信息。
- 判斷版本是否需要更新,通過簡單的版本號比較實現。
- 修改響應數據,如果需要更新,在返回數據中添加額外的字段。
1. 創建版本檢測攔截器
攔截器是NestJS中用於攔截請求和響應的重要工具。在這個場景下,我們需要創建一個攔截器,負責在響應數據發回客戶端之前,對其進行版本檢測和處理。
1import {2 CallHandler,3 ExecutionContext,4 Injectable,5 NestInterceptor,6} from "@nestjs/common";7import { Observable } from "rxjs";8import { map } from "rxjs/operators";9
10@Injectable()11export class VersionInterceptor implements NestInterceptor {12 private readonly latestVersion = "2.0.0"; // 設定最新版本號13
14 intercept(context: ExecutionContext, next: CallHandler): Observable<any> {15 const request = context.switchToHttp().getRequest();16 const version = request.headers["version"]; // 從header中獲取版本號17
18 return next.handle().pipe(19 map((data) => {20 if (version && this.needsUpdate(version)) {21 // 如果需要更新,則添加額外字段22 return {23 ...data,24 updateAvailable: true,25 updateUrl: "xxxx", // 更新地址26 latestVersion: this.latestVersion,27 message: "A new version is available, please update.",28 };29 }30 // 不需要更新,直接返回原始響應數據31 return data;32 }),33 );34 }35
36 // 版本比較邏輯37 private needsUpdate(clientVersion: string): boolean {38 return clientVersion < this.latestVersion;39 }40}
在這個攔截器中,我們通過 request.headers['version']
獲取客戶端傳來的版本號,並調用 needsUpdate
方法進行版本比較。如果客戶端版本較低,我們將額外的 updateAvailable
字段插入到返回數據中,告知用戶有新版本可用。
2. 應用攔截器
有兩種方式可以在NestJS中應用這個攔截器:局部應用或全局應用。
局部應用攔截器
如果只需要在某些特定路由上使用版本檢測功能,可以在相應的控制器中應用攔截器。
1import { Controller, Get, UseInterceptors } from "@nestjs/common";2import { VersionInterceptor } from "./version.interceptor";3
4@Controller("api")5export class AppController {6 @Get("data")7 @UseInterceptors(VersionInterceptor)8 getData() {9 return {10 data: "Here is your data",11 };12 }13}
全局應用攔截器
如果希望所有API接口都支持版本檢測,可以通過 main.ts
將攔截器全局應用。
1import { NestFactory } from "@nestjs/core";2import { AppModule } from "./app.module";3import { VersionInterceptor } from "./version.interceptor";4
5async function bootstrap() {6 const app = await NestFactory.create(AppModule);7
8 // 全局使用攔截器9 app.useGlobalInterceptors(new VersionInterceptor());10
11 await app.listen(3000);12}13bootstrap();
3. 測試接口
在完成攔截器的設置後,我們可以通過 curl
或 Postman 來測試接口。客戶端通過請求頭發送版本信息,服務器將根據版本號返回相應的響應。
請求示例
1curl -X GET http://localhost:3000/api/data -H "version: 1.0.0"
響應示例(需要更新時)
1{2 "data": "Here is your data",3 "updateAvailable": true,4 "latestVersion": "2.0.0",5 "message": "A new version is available, please update."6}
響應示例(不需要更新時)
1{2 "data": "Here is your data"3}
總結
攔截器是處理版本檢測的一個非常高效且靈活的工具,它能夠在不修改控制器邏輯的情況下,動態地修改響應數據,從而根據客戶端版本返回不同的提示信息。這個方法不僅適用於版本控制,也適用於其他類似場景,比如對響應內容進行全局格式化或添加額外的元數據。
這種方法能夠幫助我們維護API的兼容性,同時確保舊版本的客戶端能及時獲取到更新提示,提升了用戶體驗。