Interceptor’lar
Coddy'nin Node.js Journey'sinin TypeScript ve NestJS bölümünün bir parçası. Ders 23 / 24.
Her yanıtın, her işleyiciye tek tek dokunmadan ne kadar sürdüğünü belirtmesini istiyorsun. Bir interceptor, işleyiciyi sarar: next.handle() öncesindeki kod ondan önce çalışır, next.handle() çağrısının döndürdüğü sonuç üzerindeki kod ise ondan sonra çalışır.
intercept(context: ExecutionContext, next: CallHandler) {
console.log('before');
return next.handle().pipe(
tap(() => console.log('after')),
);
}next.handle(), işleyicinin sonucunu bir RxJS observable'ı, yani daha sonra gelen bir değer olarak verir. .pipe(tap(...)), değer geldiğinde Nest onu göndermeden önce bir işlev çalıştırır; bu pipe, Nest'in doğrulama pipe'larıyla ilgili değildir. Guard'lar tüm interceptor'lardan önce çalışır; bu nedenle bir guard'ın reddettiği istek interceptor'a asla ulaşmaz. Pipe uygulanmış observable'ı döndür: Nest onun taşıdığı değeri gönderir. context.switchToHttp().getResponse(), res değerini verir; bu değerin setHeader yöntemi bir başlık ekler.
app.useGlobalInterceptors(...) bir interceptor'ı tüm rotalara uygular; @UseInterceptors(...) ise tek bir denetleyiciye uygular.
Görev
Kolay“Çalıştır”, src/main.ts dosyasını kullanarak izleyicinizi yeniden başlatır. Ayrı alıştırma dosyaları ağaçta kalabilir; bu sunucu onları başlatmaz.
İstemciler ve kendi izleme sisteminiz, her isteğin ne kadar sürdüğünü bilmek ister. Her başarılı yanıta X-Response-Time yanıt başlığını ekleyin; hiçbir rotaya dokunmayın.
src/common/response-time.interceptor.tsdosyasını açın.ResponseTimeInterceptoriçindekiinterceptmetodunda önce geçerli zamanıDate.now()ile kaydedin.interceptmetodunun başındaki kod, rotanın metodu çalışmadan önce çalışır.context.switchToHttp().getResponse()ile Express'inresnesnesini alın.next.handle()rotanın metodunu çalıştırır ve sonucunu RxJS observable'ı olarak döndürür: bu, daha sonra gelen bir değerdir. Bu değeri döndürmeye devam edin, ancak zatenrxjsiçinden içe aktarılmış olantapüzerinden, observable'ın.pipe()metodunu kullanarak geçirin.tap'e verdiğiniz işlev, sonuç geldiğinde ve Nest onu göndermeden önce çalışır. Bu işlevderes.setHeaderçağrısıylaX-Response-Timedeğerini, kaydettiğiniz zamandan bu yana geçen milisaniye sayısının sonunamsekleyerek ayarlayın; örneğin3ms. (RxJS'in.pipe()metodu, 3. bölümdeki doğrulama pipe'larıyla ilgili değildir. Observable'a bir adım ekler.)src/main.tsdosyasında, yanındaki pipe ve filter ile birlikte yeni birResponseTimeInterceptorgeçirerek tüm uygulama için interceptor'ıapp.useGlobalInterceptors(...)ile kaydedin.- Yanıt gövdeleri değişmemelidir.
GET /taskshâlâ{ "items": [...], "page": 1, "total": 3, "pages": 2 }döndürür.
Deneyin: GET /tasks gönderin ve yanıtın Headers sekmesini açın. X-Response-Time başlığını, 0ms veya 2ms gibi bir değerle görürsünüz. GET /stats yanıtında da bu başlık bulunur; x-api-key: tasks-key-123 başlığıyla gönderilen { "title": "Buy milk" } gövdeli bir POST isteğinde de bulunur. Ardından bu POST isteğini anahtar olmadan gönderin: yanıt 403 olur ve X-Response-Time başlığı bulunmaz. Nest, guard'ları interceptor'lardan önce çalıştırır; bu nedenle guard, interceptor'ınız başlamadan önce isteği reddetti. Bir rota içinde fırlatılan hata da başlığın eklenmesini engeller; çünkü tap yalnızca bir sonuç geldiğinde çalışır.
Kendin dene
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> {
// Zamanı kaydedin, handler'ın çalışmasına izin verin, ardından X-Response-Time değerini ayarlayın.
return next.handle();
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
TypeScript ve NestJS bölümündeki tüm dersler
1Nest Temelleri
Sınıflar ve MetotlarMerhaba, NestBir Controller Kaydetme4Guard’lar, Filtreler, Interceptor’lar
Guard’larKendi başına pratik yap: Express playground