מיירטים
חלק מהיחידה TypeScript ו-NestJS במסלול ה-Node.js של Coddy. שיעור 23 מתוך 24.
אתם רוצים שכל תשובה תציין כמה זמן ארך הדבר, בלי לגעת בכל מטפל בנפרד. מיירט עוטף את המטפל: קוד לפני next.handle() רץ לפניו, וקוד שפועל על מה ש-next.handle() מחזירה רץ אחריו.
intercept(context: ExecutionContext, next: CallHandler) {
console.log('before');
return next.handle().pipe(
tap(() => console.log('after')),
);
}next.handle() מספקת את תוצאת המטפל כ-observable של RxJS, ערך שמגיע מאוחר יותר. .pipe(tap(...)) מריצה פונקציה כשהערך מגיע, לפני ש-Nest שולחת אותו; ל-pipe הזה אין קשר לצינורות האימות של Nest. שומרים רצים לפני כל מיירט, ולכן בקשה ששומר מסרב לה לעולם לא מגיעה אליו. החזירו את ה-observable שעבר בצינור: Nest שולחת את מה שהוא מכיל. context.switchToHttp().getResponse() מספקת את res, שה-setHeader שלה מוסיפה כותרת.
app.useGlobalInterceptors(...) מחילה מיירט על כל הנתיבים; @UseInterceptors(...) מחילה אותו על בקר אחד.
אתגר
קלהפקודה Run מפעילה שוב את המעקב שלך, באמצעות src/main.ts. קובצי התרגול הנפרדים יכולים להישאר בעץ; השרת הזה לא מפעיל אותם.
לקוחות וכלי הניטור שלך רוצים לדעת כמה זמן ארכה כל בקשה. הוסף כותרת תגובה, X-Response-Time, לכל תגובה מוצלחת, בלי לגעת באף נתיב.
- פתח את
src/common/response-time.interceptor.ts. במתודהinterceptשלResponseTimeInterceptor, תעד תחילה את השעה הנוכחית באמצעותDate.now(). קוד בראשinterceptפועל לפני המתודה של הנתיב. - קבל את
resשל Express באמצעותcontext.switchToHttp().getResponse(). next.handle()מפעיל את המתודה של הנתיב ומחזיר את התוצאה שלה כ־observable של RxJS: ערך שמגיע מאוחר יותר. המשך להחזיר אותו, אבל העבר אותו דרךtap, שכבר יובא מ־rxjs, באמצעות המתודה.pipe()של ה־observable. הפונקציה שתעביר ל־tapפועלת כשהתוצאה מגיעה, לפני ש־Nest שולח אותה. בפונקציה הזאת, קרא ל־res.setHeaderכדי להגדיר אתX-Response-Timeלמספר האלפיות השנייה שחלפו מאז שתיעדת את השעה, ואחריוms, למשל3ms. (ל־.pipe()של RxJS אין קשר לצינורות האימות שבפרק 3. היא משרשרת שלב אל ה־observable.)- ב־
src/main.ts, רשום את המיירט לכל האפליקציה באמצעותapp.useGlobalInterceptors(...), והעבר לו מופע חדש שלResponseTimeInterceptor, לצד הצינור והמסנן. - גופי התגובות לא צריכים להשתנות.
GET /tasksעדיין מחזיר{ "items": [...], "page": 1, "total": 3, "pages": 2 }.
נסה זאת: שלח GET /tasks ופתח את לשונית Headers של התגובה. תראה את X-Response-Time עם ערך כמו 0ms או 2ms. גם ל־GET /stats יש אותו, וכך גם לבקשת POST עם { "title": "Buy milk" } שנשלחה עם הכותרת x-api-key: tasks-key-123. לאחר מכן שלח את בקשת ה־POST בלי המפתח: 403, וללא X-Response-Time. Nest מפעיל guards לפני מיירטים, ולכן ה־guard דחה את הבקשה לפני שהמיירט שלך התחיל לפעול. גם שגיאה שנזרקת בתוך נתיב מדלגת על הכותרת, מפני ש־tap פועל רק כשהתוצאה מגיעה.
נסו בעצמכם
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, tap } from 'rxjs';
@Injectable()
export class ResponseTimeInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
// רשמו את השעה, אפשרו ל-handler לפעול, ואז הגדירו את X-Response-Time.
return next.handle();
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה TypeScript ו-NestJS
1יסודות Nest
מחלקות ומתודותשלום, Nestרישום בקר4משמרים, מסננים ומיירטים
משמריםתרגלו בעצמכם: Express אונליין