Angular HttpClient ve Interceptor'lar 2026: HTTP İstek Yönetimi ve Mülakat Soruları
Angular 20 fonksiyonel interceptor'larına kapsamlı bir rehber: kimlik doğrulama token enjeksiyonundan üstel geri çekilme ile yeniden deneme mantığına kadar. Mülakat soruları ve production kalıpları içerir.

Angular HttpClient interceptor'ları, uygulamaların HTTP isteklerini nasıl işlediğini dönüştürür — kimlik doğrulama başlıkları eklemekten yeniden deneme mantığı uygulamaya kadar. Angular 20, fonksiyonel interceptor'ları önerilen yaklaşım olarak standartlaştırdı ve eski sınıf tabanlı kalıbı daha öngörülebilir ve tree-shakeable bir API ile değiştirdi.
Angular 20, sınıf tabanlı interceptor'lar yerine withInterceptors() ile fonksiyonel interceptor'ları önerir. Fonksiyonel interceptor'lar daha öngörülebilir yürütme sırasına sahiptir ve standalone component'lerle daha iyi entegre olur.
provideHttpClient ile HttpClient Kurulumu
Interceptor'lar yazmadan önce, uygulama bootstrap'inde HttpClient yapılandırılmalıdır. Angular'ın standalone mimarisi, eski HttpClientModule yerine provideHttpClient() kullanır.
Kurulum, uygulama yapılandırmasında gerçekleşir:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { AppComponent } from './app/app.component';
import { authInterceptor } from './interceptors/auth.interceptor';
import { loggingInterceptor } from './interceptors/logging.interceptor';
bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(
// Interceptor'lar dizi sırasına göre çalışır
withInterceptors([authInterceptor, loggingInterceptor])
),
],
});Interceptor'lar dizide belirtilen sırayla çalışır. İlk interceptor giden isteği ilk işler ve son interceptor yanıtı ilk görür.
Fonksiyonel Interceptor Anatomisi
Fonksiyonel bir interceptor, isteği ve bir next fonksiyonunu alır. next(req) çağrısı, isteği zincirdeki bir sonraki interceptor'a veya bu son interceptor'sa backend'e iletir.
Temel yapı şöyle görünür:
import { HttpInterceptorFn, HttpRequest, HttpHandlerFn, HttpEvent } from '@angular/common/http';
import { Observable, tap } from 'rxjs';
export const loggingInterceptor: HttpInterceptorFn = (
req: HttpRequest<unknown>,
next: HttpHandlerFn
): Observable<HttpEvent<unknown>> => {
const startTime = performance.now();
console.log(`[HTTP] ${req.method} ${req.url}`);
return next(req).pipe(
tap({
next: () => {
const duration = Math.round(performance.now() - startTime);
console.log(`[HTTP] ${req.method} ${req.url} completed in ${duration}ms`);
},
error: (err) => {
console.error(`[HTTP] ${req.method} ${req.url} failed:`, err.message);
},
})
);
};Interceptor, istek metodunu ve URL'yi loglar, ardından yanıt süresini ölçer. tap operatörü, yanıtı değiştirmeden gözlemler.
Token Enjeksiyonlu Kimlik Doğrulama Interceptor'ı
Çoğu uygulama, giden isteklere kimlik doğrulama token'ları eklemeyi gerektirir. Interceptor, HttpRequest nesneleri değiştirilemez olduğundan, isteği Authorization başlığıyla klonlar.
Bu kalıp, token'ı bir servisten alır ve ekler:
import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService } from '../services/auth.service';
export const authInterceptor: HttpInterceptorFn = (req, next) => {
// Angular'ın inject() fonksiyonunu kullanarak servis enjeksiyonu
const authService = inject(AuthService);
const token = authService.getAccessToken();
// Public endpoint'ler için auth başlığını atla
if (req.url.includes('/public/') || !token) {
return next(req);
}
// Authorization başlığıyla isteği klonla
const authReq = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
return next(authReq);
};inject() fonksiyonu çalışır çünkü interceptor'lar Angular'ın enjeksiyon bağlamında çalışır. Bu, sınıf tabanlı interceptor'lardaki constructor enjeksiyonu şablonunu ortadan kaldırır.
Hata Yönetimi ve Yeniden Deneme Mantığı
Ağ hataları olur. Yeniden deneme interceptor'ı, başarısız istekleri üstel geri çekilme ile otomatik olarak yeniden deneyebilir ve her HTTP çağrısında değişiklik gerektirmeden güvenilirliği artırır.
RxJS operatörleri yeniden deneme mantığını yönetir:
import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';
import { retry, timer } from 'rxjs';
export const retryInterceptor: HttpInterceptorFn = (req, next) => {
// Yalnızca GET isteklerini yeniden dene (idempotent)
if (req.method !== 'GET') {
return next(req);
}
return next(req).pipe(
retry({
count: 3,
delay: (error: HttpErrorResponse, retryCount: number) => {
// İstemci hatalarını yeniden deneme (4xx)
if (error.status >= 400 && error.status < 500) {
throw error;
}
// Üstel geri çekilme: 1s, 2s, 4s
const delayMs = Math.pow(2, retryCount - 1) * 1000;
console.log(`Yeniden deneme #${retryCount} - ${delayMs}ms sonra`);
return timer(delayMs);
},
})
);
};Interceptor yalnızca GET isteklerini yeniden dener çünkü POST, PUT ve DELETE idempotent değildir. İstemci hataları (4xx), sunucu isteği açıkça reddettiği için yeniden denemeleri atlar.
Angular mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
HttpContext ile Yanıt Önbellekleme
HttpClient, interceptor'lar ve çağıran kod arasında meta veri geçirmek için HttpContext sağlar. Önbellekleme interceptor'ı, önbellek davranışını belirlemek için context token'larını okuyabilir.
Önbellek token'ı ve interceptor birlikte çalışır:
import { HttpInterceptorFn, HttpContextToken, HttpResponse } from '@angular/common/http';
import { of, tap } from 'rxjs';
// İstek başına önbelleklemeyi kontrol etmek için context token'ı
export const CACHE_REQUEST = new HttpContextToken<boolean>(() => false);
const cache = new Map<string, HttpResponse<unknown>>();
export const cacheInterceptor: HttpInterceptorFn = (req, next) => {
// Yalnızca context aracılığıyla açıkça istendiğinde önbellekle
if (!req.context.get(CACHE_REQUEST) || req.method !== 'GET') {
return next(req);
}
const cacheKey = req.urlWithParams;
const cachedResponse = cache.get(cacheKey);
if (cachedResponse) {
console.log(`[Cache] HIT: ${cacheKey}`);
return of(cachedResponse.clone());
}
return next(req).pipe(
tap((event) => {
if (event instanceof HttpResponse) {
console.log(`[Cache] STORE: ${cacheKey}`);
cache.set(cacheKey, event.clone());
}
})
);
};Çağıran kod, context token'ı ile önbelleklemeyi etkinleştirir:
import { HttpClient, HttpContext } from '@angular/common/http';
import { CACHE_REQUEST } from '../interceptors/cache.interceptor';
export class UserService {
constructor(private http: HttpClient) {}
getUser(id: string) {
return this.http.get(`/api/users/${id}`, {
context: new HttpContext().set(CACHE_REQUEST, true),
});
}
}Bu kalıp, önbellekleme davranışını global yapılandırmada gizlemek yerine çağrı noktasında açık tutar.
401 İşleme ile Token Yenileme
Erişim token'ları süresi dolduğunda, sunucu 401 yanıtı döndürür. Bir interceptor bunu yakalayabilir, token'ı yenileyebilir ve orijinal isteği şeffaf bir şekilde yeniden deneyebilir.
Yenileme mantığı birden fazla eşzamanlı isteği koordine eder:
import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';
import { inject } from '@angular/core';
import { catchError, switchMap, throwError, BehaviorSubject, filter, take } from 'rxjs';
import { AuthService } from '../services/auth.service';
let isRefreshing = false;
const refreshTokenSubject = new BehaviorSubject<string | null>(null);
export const tokenRefreshInterceptor: HttpInterceptorFn = (req, next) => {
const authService = inject(AuthService);
return next(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status !== 401 || req.url.includes('/auth/refresh')) {
return throwError(() => error);
}
if (isRefreshing) {
// Yenilemenin tamamlanmasını bekle
return refreshTokenSubject.pipe(
filter((token) => token !== null),
take(1),
switchMap((token) => {
const retryReq = req.clone({
setHeaders: { Authorization: `Bearer ${token}` },
});
return next(retryReq);
})
);
}
isRefreshing = true;
refreshTokenSubject.next(null);
return authService.refreshToken().pipe(
switchMap((response) => {
isRefreshing = false;
refreshTokenSubject.next(response.accessToken);
const retryReq = req.clone({
setHeaders: { Authorization: `Bearer ${response.accessToken}` },
});
return next(retryReq);
}),
catchError((refreshError) => {
isRefreshing = false;
authService.logout();
return throwError(() => refreshError);
})
);
})
);
};BehaviorSubject, birkaç istek aynı anda başarısız olduğunda birden fazla yenileme çağrısını önler. Token yenilendiğinde, kuyruktaki tüm istekler yeni token ile yeniden denenir.
Mülakat Soruları: HttpClient ve Interceptor'lar
Teknik mülakatlar genellikle HTTP işleme kalıplarının anlaşılmasını araştırır. Bu sorular Angular pozisyonlarında sıkça karşılaşılır.
S: Fonksiyonel interceptor'lar neden sınıf tabanlı interceptor'lara tercih edilir?
Fonksiyonel interceptor'lar daha öngörülebilir yürütme sırasına sahiptir. Angular dokümantasyonu, withInterceptors() ile fonksiyonel interceptor'ların katı dizi sırasını koruduğunu, DI tabanlı interceptor'ların karmaşık modül hiyerarşilerinde sıralama sorunlarına sahip olabileceğini belirtir. Fonksiyonel interceptor'lar ayrıca daha iyi tree-shake oldukları için daha küçük bundle'lar üretir.
S: Belirli isteklerde interceptor'ın çalışmasını nasıl engellersiniz?
İki yaklaşım vardır. Birincisi, interceptor'da URL kalıbını kontrol etmek ve hariç tutulan yollar için değişiklik yapmadan next(req) çağırmak. İkincisi, çağıran kodun interceptor davranışından çıkmak için ayarladığı HttpContext token'larını kullanmak. Context yaklaşımı, hariç tutma kararını çağrı noktasında tutar.
S: Interceptor'da next() çağırmayı unutursanız ne olur?
İstek asla sunucuya ulaşmaz. next() tarafından döndürülen Observable, interceptor zincirinin geri kalanını ve gerçek HTTP çağrısını temsil eder. Çağrılmadan, downstream interceptor'lar ve backend isteği asla görmez. Bu, önbellekten yanıt döndüren önbellekleme interceptor'ları için kasıtlıdır.
S: Token yenileme sırasında eşzamanlı istekleri nasıl yönetirsiniz?
Koordinasyon için BehaviorSubject kullanın. İlk 401 yenilemeyi tetiklediğinde, bir bayrak ayarlayın ve subject'e null emit edin. Sonraki 401'ler, yeni token gelene kadar filter ile subject'i bekler. Bu, birden fazla yenileme çağrısını önler ve tüm bekleyen isteklerin aynı taze token ile yeniden denemesini sağlar.
S: Interceptor'lar yanıt gövdesini değiştirebilir mi?
Evet. HttpResponse nesnelerini dönüştürmek için next() tarafından döndürülen Observable'da map() kullanın. Yanıtlar değiştirilemez olduğundan, değiştirilmiş gövdelerle klonlayın. Bu kalıp, hesaplanmış alanlar eklemek, API zarflarını açmak veya veri yapılarını normalize etmek için çalışır.
Daha fazla Angular mülakat hazırlığı için HttpClient mülakat soruları modülüne bakın.
Fonksiyonel Interceptor'ları Test Etme
Interceptor'lar, mock edilmiş HTTP handler'larla test edilmelidir. Angular'ın HttpTestingController'ı, provideHttpClient() aracılığıyla kaydedilen interceptor'larla çalışır.
Bir test kurulumu şöyle görünür:
import { TestBed } from '@angular/core/testing';
import { HttpClient, provideHttpClient, withInterceptors } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { authInterceptor } from './auth.interceptor';
import { AuthService } from '../services/auth.service';
describe('authInterceptor', () => {
let httpClient: HttpClient;
let httpTesting: HttpTestingController;
let authServiceSpy: jasmine.SpyObj<AuthService>;
beforeEach(() => {
authServiceSpy = jasmine.createSpyObj('AuthService', ['getAccessToken']);
TestBed.configureTestingModule({
providers: [
provideHttpClient(withInterceptors([authInterceptor])),
provideHttpClientTesting(),
{ provide: AuthService, useValue: authServiceSpy },
],
});
httpClient = TestBed.inject(HttpClient);
httpTesting = TestBed.inject(HttpTestingController);
});
it('should add Authorization header when token exists', () => {
authServiceSpy.getAccessToken.and.returnValue('test-token');
httpClient.get('/api/data').subscribe();
const req = httpTesting.expectOne('/api/data');
expect(req.request.headers.get('Authorization')).toBe('Bearer test-token');
req.flush({ data: 'test' });
});
it('should skip Authorization for public endpoints', () => {
authServiceSpy.getAccessToken.and.returnValue('test-token');
httpClient.get('/public/health').subscribe();
const req = httpTesting.expectOne('/public/health');
expect(req.request.headers.has('Authorization')).toBeFalse();
req.flush({ status: 'ok' });
});
});Test, gerçek ağ istekleri yapmadan hem başlık enjeksiyonunu hem de public endpoint istisnasını doğrular.
Production Kalıpları: Interceptor'ları Birleştirme
Gerçek uygulamalar birden fazla interceptor'ı yığınlar. Sıra önemlidir: kimlik doğrulama loglama'dan önce, önbellekleme yeniden deneme mantığından önce olmalıdır.
Bir production yapılandırması şöyle görünebilir:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { AppComponent } from './app/app.component';
import { authInterceptor } from './interceptors/auth.interceptor';
import { tokenRefreshInterceptor } from './interceptors/token-refresh.interceptor';
import { cacheInterceptor } from './interceptors/cache.interceptor';
import { retryInterceptor } from './interceptors/retry.interceptor';
import { loggingInterceptor } from './interceptors/logging.interceptor';
bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(
withInterceptors([
// Sıra: auth -> refresh -> cache -> retry -> logging
authInterceptor,
tokenRefreshInterceptor,
cacheInterceptor,
retryInterceptor,
loggingInterceptor,
])
),
],
});Bu sıralama, token'ların yenileme işleminden önce eklenmesini, önbellek kontrollerinin yeniden denemelerden önce gerçekleşmesini ve loglama'nın son zamanlamayı kaydetmesini sağlar.
Daha fazla Angular kalıbı için, interceptor'larda kullanılan operatörleri kapsayan RxJS temelleri modülüne bakın.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Angular HttpClient Interceptor'ları için Temel Çıkarımlar
withInterceptors()ile fonksiyonel interceptor'lar Angular 20 standardıdır, sınıf tabanlı alternatiflere göre öngörülebilir sıralama ve daha iyi tree-shaking sunar- Constructor şablonu olmadan servislere erişmek için interceptor'ların içinde
inject()kullanın HttpRequestnesneleri değiştirilemez olduğundan başlıkları değiştirmek içinreq.clone()ile istekleri klonlayınHttpContexttoken'ları, istek başına davranışı global yapılandırmada gizlemek yerine çağrı noktasında açık yapar- Token yenileme interceptor'ları, birden fazla yenileme çağrısını önlemek için
BehaviorSubjectile eşzamanlı istekleri koordine etmelidir - Interceptor sırası önemlidir: kimlik doğrulama önbelleklemeden önce, önbellekleme yeniden denemeden önce, loglama en sonda
Angular kodundaki hatayı bulabilir misin?
Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Yazan:
Anthony Fillion-MailletSharpSkill kurucusu
10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.
22 Ağustos 2026 tarihinde güncellendi
Paylaş
İlgili makaleler

2026'da Angular Signals ve Computed: İnce Taneli Reaktivite ve Mülakat Soruları
Angular 20+ ile Angular Signals, computed, effect ve linkedSignal konularında uzmanlaşın. İnce taneli reaktivite desenleri ve mülakat hazırlığı.

2026'da İleri Düzey Angular Dependency Injection: Providers, Tokens ve Mülakat Soruları
Angular'da ileri düzey Dependency Injection mekanizmalarına kapsamlı bir bakış. Providers, InjectionToken, injector hiyerarşisi ve teknik mülakatlarda karşılaşılan sorular.

Angular Control Flow Sözdizimi 2026: @if, @for, @switch ve Mülakat Soruları
Angular'da blok tabanlı control flow sözdizimi için kapsamlı rehber. @if, @for, @switch kullanımını pratik kod örnekleriyle öğrenin ve teknik mülakatlarına hazırlanın.