
كيفية البدء سريعًا باستخدام VUE3.0: أدخل وتعلم
Nest.js هو إطار عمل خلفي لـ Nodejs، وهو يتضمن الأنظمة الأساسية السريعة ومنصات http الأخرى لحل المشكلات المعمارية. فهو يوفر MVC وIOC وAOP وميزات معمارية أخرى لا يمتلكها Express، مما يسهل صيانة الكود وتوسيعه.
ماذا يعني MVC وIOC وAOP هنا؟ دعونا ننظر إليها بشكل منفصل:
MVC هو اختصار لـ Model View Controller. ضمن بنية MVC، سيتم إرسال الطلب أولاً إلى وحدة التحكم، والتي سترسل خدمة طبقة النموذج لإكمال منطق الأعمال، ثم تعيد العرض المقابل.

يوفر Nest.js مصمم الديكور @Controller للإعلان عن وحدة التحكم:

سيتم الإعلان عن الخدمة باستخدام مصمم الديكور @Injectable:

سيتم فحص الفئات المعلنة من خلال @Controller وInjectable بواسطة Nest.js، وسيتم إنشاء الكائنات المقابلة وإضافتها إلى الحاوية، وسيتم حقن كل هذه الكائنات تلقائيًا وفقًا للتبعيات المعلنة في المُنشئ، أي DI (التبعية). inject) ) ، تسمى هذه الفكرة IOC (معكوس التحكم).
تتمثل ميزة بنية IOC في عدم الحاجة إلى إنشاء كائنات يدويًا وتمريرها إلى مُنشئي كائنات مختلفة بناءً على التبعيات، حيث يتم فحص كل شيء وإنشائه وإدخاله تلقائيًا.
بالإضافة إلى ذلك، يوفر Nest.js أيضًا قدرة AOP (البرمجة الموجهة نحو الجانب)، وهي قدرة البرمجة الموجهة نحو الجانب:
ماذا يعني AOP؟ ما هي البرمجة الموجهة نحو الجانب؟
قد يمر الطلب عبر منطق وحدة التحكم والخدمة والمستودع (الوصول إلى قاعدة البيانات):

إذا كنت تريد إضافة بعض المنطق العام إلى رابط المكالمة هذا، فكيف يجب عليك إضافته؟ مثل التسجيل والتحكم في الأذونات ومعالجة الاستثناءات وما إلى ذلك.
ما يسهل التفكير فيه هو تحويل كود طبقة وحدة التحكم مباشرة وإضافة هذا المنطق. ينجح هذا، لكنه ليس أنيقًا لأن هذه المنطق المشترك يغزو منطق الأعمال. هل يمكننا إضافة السجلات والأذونات وما إلى ذلك بشفافية إلى منطق الأعمال هذا؟
هل من الممكن إضافة مرحلة لتنفيذ المنطق المشترك قبل وبعد استدعاء وحدة التحكم؟
على سبيل المثال:

تسمى نقاط التوسع الأفقية هذه بالجوانب، وتسمى طريقة البرمجة هذه التي تضيف بعض منطق الجوانب بشفافية AOP (البرمجة الموجهة نحو الجوانب).
تتمثل ميزة AOP في أنه يمكنه فصل بعض المنطق العام إلى جوانب والحفاظ على منطق الأعمال نقيًا. وبهذه الطريقة، يمكن إعادة استخدام منطق الجوانب وإضافته وحذفه ديناميكيًا.
في الواقع، يعد النموذج البصلي للبرامج الوسيطة لـ Express بمثابة تطبيق من AOP، لأنه يمكنك لف طبقة من الخارج بشفافية وإضافة بعض المنطق، ولن تكون الطبقة الداخلية مرئية.
لدى Nest.js المزيد من الطرق لتنفيذ AOP، وهناك خمس طرق في المجموع، بما في ذلك البرامج الوسيطة، والحرس، والأنابيب، وInteceptor، وExceptionFilter:،
تعتمد Nest.js على Express ويمكنها استخدام البرامج الوسيطة بشكل طبيعي، ولكن تم تقسيمها بشكل أكبر. ، مقسمة إلى برامج وسيطة عالمية وبرامج وسيطة للتوجيه:
البرامج الوسيطة العالمية هي برامج وسيطة لـ Express تتم إضافة بعض منطق المعالجة قبل الطلب وبعده:

البرامج الوسيطة للتوجيه مخصصة لمسار معين، بنطاق أصغر:

يرث هذا المفهوم Express مباشرةً ويسهل فهمه.
دعونا نلقي نظرة على بعض المفاهيم الموسعة لـ Nest.js، مثل Guard:
Guard تعني حماية التوجيه، ويمكن استخدامها لتحديد الأذونات قبل استدعاء وحدة التحكم وإرجاع صحيح أو خطأ لتحديد ما إذا كان سيتم تحريرها:

طريقة إنشاء الحرس هي كما يلي:

يحتاج Guard إلى تنفيذ واجهة CanActivate وطريقة canActive، حيث يمكنه الحصول على المعلومات المطلوبة من السياق، ثم إجراء بعض التحقق من الأذونات والمعالجة الأخرى قبل إرجاع صحيح أو خطأ.
قم بإضافته إلى حاوية IOC من خلال مصمم الديكور @Injectable، ثم قم بتمكينه في وحدة التحكم:

لا تحتاج وحدة التحكم نفسها إلى التعديل، ولكن تتم إضافة منطق حكم الإذن بشفافية، وهذه هي فائدة بنية AOP.
وكما تدعم البرامج الوسيطة المستويات العالمية ومستويات المسار، يمكن أيضًا تمكين Guard عالميًا:

يمكن لـ Guard تجريد منطق التحكم في الوصول للتوجيه، لكن لا يمكنه تعديل الطلبات والاستجابات. يمكن لهذا المنطق استخدام Interceptor:
Interceptor يعني أنه يمكنك إضافة بعض المنطق قبل وبعد طريقة التحكم الهدف:

طريقة إنشاء Inteceptor هي كما يلي:

يحتاج المعترض إلى تنفيذ واجهة NestInterceptor وسيستدعي استدعاء next.handle() وحدة التحكم الهدف، ويمكنك إضافة بعض منطق المعالجة قبل وبعد.
قد يكون منطق المعالجة قبل وبعد وحدة التحكم غير متزامن. يقوم Nest.js بتنظيمها من خلال rxjs، بحيث يمكنك استخدام عوامل تشغيل مختلفة لـ rxjs.
يدعم Interceptor تمكين كل مسار على حدة، مما يؤثر فقط على وحدة تحكم معينة، كما يدعم أيضًا التمكين الشامل، مما يؤثر على جميع وحدات التحكم:


بالإضافة إلى التحكم في أذونات المسارات والمعالجة قبل وحدة التحكم الهدف وبعدها، والتي تعد كلها منطقًا شائعًا، فإن معالجة المعلمات هي أيضًا منطق شائع، لذلك يستخرج Nest.js أيضًا الجوانب المقابلة، أي Pipe:
الأنابيب تعني الأنابيب، وتستخدم للقيام ببعض التحقق من المعلمات وتحويلها:

طريقة إنشاء الأنابيب هي كما يلي:

يحتاج Pipe إلى تنفيذ واجهة PipeTransform وطريقة التحويل، والتي يمكنها التحقق من المعلمة على قيمة المعلمة الواردة، مثل ما إذا كان التنسيق والنوع صحيحين، وإذا لم يكن صحيحًا، فسيتم طرح استثناء. يمكنك أيضًا إجراء التحويل وإرجاع القيمة المحولة.
هناك 8 أنابيب مدمجة، ويمكن رؤية معانيها من الأسماء:
ValidationPipeParseIntPipeParseBoolPipeParseArrayPipeParseUUIDPipeDefaultValuePipeParseEnumPipeParseFloatPipeوبالمثل، يمكن أن يسري مفعول Pipe فقط على مسار معين، أو يمكن أن يسري مفعوله على كل مسار:


سواء كان الأنبوب أو الحارس أو المعترض أو وحدة التحكم التي تم استدعاؤها أخيرًا، يمكن طرح بعض الاستثناءات أثناء العملية. كيفية الرد على استثناءات معينة؟
يُعد تعيين الاستثناءات للاستجابات هذا أيضًا منطقًا شائعًا، حيث يوفر Nest.js دعم ExceptionFilter:
يمكن لـExceptionFilter التعامل مع الاستثناءات التي تم طرحها وإرجاع الاستجابات المقابلة:

شكل إنشاء ExceptionFilter هو كما يلي:

أولاً، تحتاج إلى تنفيذ واجهة ExceptionFilter وطريقة الالتقاط لاعتراض الاستثناءات، ومع ذلك، يجب الإعلان عن الاستثناءات التي تريد اعتراضها باستخدام مصمم @Catch، بعد اعتراض الاستثناء، يمكنك الاستجابة بالاستثناء المطابق المستخدم موجه أكثر ودية.
بالطبع، لن يتم التعامل مع جميع الاستثناءات إلا الاستثناءات التي ترث HttpException سيتم التعامل معها بواسطة ExceptionFilter. يحتوي Nest.js على العديد من الفئات الفرعية المضمنة في HttpException:
BadRequestExceptionUnauthorizedExceptionNotFoundExceptionForbiddenExceptionNotAcceptableExceptionRequestTimeoutExceptionConflictExceptionGoneExceptionUnsupportedMediaTypeExceptionUnprocessableExceptionInternalServerErrorExceptionNotImplementedExceptionPayloadTooLargeExceptionBadGatewayExceptionServiceUnavailableExceptionGatewayTimeoutExceptionبالطبع، يمكنك أيضًا تمديده بنفسك:

يدرك Nest.js المراسلات بين الاستثناءات والاستجابات بهذه الطريقة، وطالما تم طرح استثناءات HttpExceptions مختلفة في الكود، فسيتم إرجاع الاستجابات المقابلة، وهو أمر مريح للغاية.
وبالمثل، يمكن لـ ExceptionFilter أيضًا اختيار تفعيله عالميًا أو تفعيله على مسار معين:
مسار معين:

عالمي:

نحن نفهم آلية AOP التي تقدمها Nest.js، ولكن ما هي علاقة الترتيب الخاصة بها؟
يمكنمثل البرامج الوسيطة والحرس والأنابيب والمعترض ومرشح الاستثناء، إضافة منطق معالجة معين بشفافية إلى مسار معين أو جميع المسارات. وهذه هي فائدة AOP.
ولكن ما هي العلاقة التسلسلية بينهما؟
تعتمد علاقة الاتصال على الكود المصدري.
رمز المصدر المقابل هو كما يلي:

من الواضح أنه عند الدخول إلى هذا المسار، سيتم استدعاء الحرس أولاً لتحديد ما إذا كان هناك إذن، وما إلى ذلك. إذا لم يكن هناك إذن، فسيتم طرح استثناء هنا:

سيتم التعامل مع HttpException الذي تم طرحه بواسطة ExceptionFilter.
إذا كان لديك إذن، فسيتم استدعاء المعترض، وسينظم المعترض سلسلة، ويستدعي واحدًا تلو الآخر، ثم يستدعي أخيرًا طريقة التحكم:

قبل استدعاء طريقة التحكم، سيتم استخدام الأنبوب لمعالجة المعلمات:

سيتم تحويل كل معلمة:

من السهل التفكير في توقيت استدعاء ExceptionFilter، وهو معالجة الاستثناء قبل الاستجابة.
تعد البرامج الوسيطة مفهومًا صريحًا، حيث يرثها Nest.js فقط، ويتم استدعاؤها في الطبقة الخارجية.
هذا هو تسلسل الاتصال لآليات AOP هذه. بمجرد الانتهاء من حل هذه الأمور، سيكون لديك فهم جيد لـ Nest.js.
يتم تغليف Nest.js استنادًا إلى منصة http السريعة، ويطبق أفكارًا معمارية مثل MVC، وIOC، وAOP.
MVC هو تقسيم النموذج ووحدة التحكم في العرض، ويمر الطلب أولاً عبر وحدة التحكم، ثم يستدعي الخدمة والمستودع لطبقة النموذج لإكمال منطق العمل، ويعيد العرض المقابل في النهاية.
تعني IOC أن Nest.js سيقوم تلقائيًا بفحص الفئات باستخدام أدوات الديكور @Controller و@Injectable، وإنشاء كائناتها، وحقن الكائنات التي تعتمد عليها تلقائيًا بناءً على التبعيات، مما يزيل مشكلة إنشاء الكائنات وتجميعها يدويًا.
يقوم AOP باستخراج المنطق العام وإضافته إلى مكان معين من خلال الجوانب، ويمكنه إعادة استخدام منطق الجوانب وإضافته وحذفه ديناميكيًا.
تعد البرامج الوسيطة وGuard وInterceptor وPipe وExceptionFileter من Nest.js جميعها تطبيقات لأفكار AOP، وهي مجرد جوانب في مواقع مختلفة ويمكن تطبيقها جميعًا بمرونة على مسار معين أو جميع المسارات.
لقد نظرنا إلى تسلسل الاتصال الخاص بهم من خلال الكود المصدري وهو مفهوم Express. في الطبقة الخارجية، سيتم استدعاء Guard أولاً لتحديد ما إذا كان المسار لديه إذن للوصول سيتم استدعاء المعترض لتوسيع بعض المنطق ذهابًا وإيابًا، واستدعاء Pipe للتحقق من المعلمات وتحويلها قبل الوصول إلى وحدة التحكم المستهدفة. ستتم معالجة كافة استثناءات HttpException بواسطة ExceptionFilter وإرجاع استجابات مختلفة.
يستخدم Nest.js بنية AOP هذه لتحقيق بنية مقترنة بشكل غير محكم وسهلة الصيانة والتوسيع.
هل شعرت بفوائد بنية AOP؟