| وجه المقارنة المعمارية | المعترضات التقليدية القائمة على الأصناف (`Class-based`) | المعترضات الوظيفية الحديثة (`Functional Interceptors`) |
|---|---|---|
| طريقة التنفيذ والكتابة | صنف برمجي يعتمد على واجهة `HttpInterceptor` ويحتاج لتسجيل معقد | دالة برمجية نقية (`Pure Function`) تُستدعى مباشرة وتمرر عبر `withInterceptors` |
| الاعتماديات وحقنها | تتطلب حقن الاعتماديات داخل constructor الصنف بطرق معقدة أحياناً | تستفيد مباشرة من دالة `inject()` الحديثة بكل مرونة وداخل نطاق الدالة |
| سهولة التركيب والصيانة | معقدة عند الرغبة في دمج أو ترتيب عدة معترضات بالتسلسل | سهلة للغاية وقابلة للتركيب والتسلسل بسلاسة تامة داخل إعدادات التطبيق |
تحولت معالجات الطلبات والعمليات الوسيطة (Interceptors) من الأنماط القائمة على الأصناف القديمة إلى الدلالات الوظيفية الخالصة (Functional Interceptors). تتيح لك هذه المعالجات الوظيفية اعتراض طلبات HTTP واستجاباتها، تعديل الترويسات (Headers)، معالجة الأخطاء مركزياً، وتوجيه مسار تدفق البيانات بكفاءة عالية عبر خطوط أنابيب نظيفة وقابلة للتركيب (Composable Pipelines).
يعتمد النظام الوظيفي الجديد على تمرير الطلب (HttpRequest) مع دالة تنفيذ (HttpHandlerFn) تسمى لتمرير الطلب إلى المعالج التالي في السلسلة، مما يمنح المطور تحكماً كاملاً في ما قبل وبعد إرسال الطلب للخادم.
التخلص من هيكل الأصناف والـ Classes يقلل من حجم الملفات الناتجة (Bundle Size) ويسهل اختبار المعالجات بشكل مستقل تماماً عبر استدعاء الدالة وتمرير بيانات وهمية لها.
| 1 | import { HttpInterceptorFn, HttpRequest, HttpHandlerFn, HttpEvent } from '@angular/common/http'; |
| 2 | import { inject } from '@angular/core'; |
| 3 | import { Observable } from 'rxjs'; |
| 4 | |
| 5 | export const authInterceptor: HttpInterceptorFn = ( |
| 6 | req: HttpRequest<unknown>, |
| 7 | next: HttpHandlerFn |
| 8 | ): Observable<HttpEvent<unknown>> => { |
| 9 | // حقن أي خدمة مطلوبة مباشرة عبر دالة inject الحديثة |
| 10 | // const authService = inject(AuthService); |
| 11 | |
| 12 | const clonedRequest = req.clone({ |
| 13 | setHeaders: { |
| 14 | 'Authorization': 'Bearer enterprise-token-22.1', |
| 15 | 'X-Client-Version': '22.1.0' |
| 16 | } |
| 17 | }); |
| 18 | |
| 19 | // تمرير الطلب المعدل إلى المعالج التالي في السلسلة |
| 20 | return next(clonedRequest); |
| 21 | }; |
| 1 | import { ApplicationConfig } from '@angular/core'; |
| 2 | import { provideHttpClient, withInterceptors } from '@angular/common/http'; |
| 3 | import { authInterceptor } from './auth-interceptor'; |
| 4 | |
| 5 | export const appConfig: ApplicationConfig = { |
| 6 | providers: [ |
| 7 | // تفعيل الـ HttpClient مع دمج المعترضات الوظيفية بسلاسة |
| 8 | provideHttpClient( |
| 9 | withInterceptors([authInterceptor]) |
| 10 | ) |
| 11 | ] |
| 12 | }; |
⚠️ تحذير
احذر من تعديل الكائن الأصلي للطلب مباشرة (Mutation)! كائنات الطلب في أنگولر غير قابلة للتغيير (Immutable). يجب عليك دائماً استخدام req.clone() لإنشاء نسخة معدلة قبل تمريرها إلى دالة المعالجة التالية next().