كيفية بناء تطبيقات لا خادمية باستخدام Azure Functions و Blazor WebAssembly

دقائق القراءة: 16

مقدمة في بناء التطبيقات اللا خادمية باستخدام Azure و Blazor

في هذا المقال، سنتعمق في كيفية دمج بنية التطبيقات اللا خادمية (Serverless) من Azure مع تطبيقات Blazor WebAssembly لإنشاء حلول ويب حديثة وفعالة. سنقوم بتطوير تطبيق عملي يعرض قائمة بالأسئلة المتكررة (FAQ) حول Covid-19، وذلك لتوضيح المفاهيم بشكل ملموس. ستشمل رحلتنا التقنية الخطوات التالية:

  • إنشاء قاعدة بيانات Azure Cosmos DB لتكون المستودع الرئيسي لبيانات الأسئلة والأجوبة.
  • استخدام تطبيق وظائف Azure Function App لجلب البيانات من Cosmos DB.
  • نشر تطبيق الوظائف على Azure لجعله متاحًا عالميًا عبر نقطة نهاية API.
  • استهلاك نقطة نهاية API هذه ضمن تطبيق Blazor WebAssembly لعرض الأسئلة والأجوبة.

سيتم عرض الأسئلة المتكررة في تصميم بطاقات جذاب باستخدام مكتبة Bootstrap. يمكنكم معاينة التطبيق الحي المنشور على Azure عبر الرابط: https://covid19-faq.azurewebsites.net/.

ما هي المعمارية اللا خادمية (Serverless)؟

في التطبيقات التقليدية، مثل التطبيقات ثلاثية الطبقات (3-tier app)، يقوم العميل بطلب الموارد من الخادم، والذي بدوره يعالج الطلب ويستجيب بالبيانات المناسبة.

مخطط معماري لتطبيق تقليدي ثلاثي الطبقات يوضح تفاعل العميل والخادم وقاعدة البيانات

إلا أن هذه المعمارية تواجه بعض التحديات الجوهرية. على سبيل المثال، يتطلب الأمر وجود خادم يعمل بشكل مستمر على مدار الساعة طوال أيام الأسبوع، حتى في غياب الطلبات، مما يزيد من التكاليف التشغيلية للحفاظ على توفره. كما أن قابلية التوسع (scaling) تمثل مشكلة أخرى؛ ففي حال ازدياد حركة المرور بشكل كبير، يصبح توسيع نطاق جميع الخوادم عملية معقدة وتستهلك الكثير من الموارد.

الحل الفعال لهذه المشكلات يكمن في معمارية الويب اللا خادمية. في هذا النموذج، يرسل العميل الطلبات إلى حساب تخزين للملفات بدلاً من الخادم التقليدي. يقوم حساب التخزين هذا بإرجاع صفحة index.html بالإضافة إلى بعض الشيفرة التي تحتاج إلى عرضها في المتصفح. وبما أنه لا يوجد خادم لتوليد الصفحة، فإننا نعتمد على المتصفح للقيام بهذه المهمة. يتم تنفيذ جميع منطق رسم العناصر أو تحديثها داخل المتصفح نفسه. لا يوجد لدينا أي خادم في الواجهة الخلفية؛ بل مجرد حساب تخزين يحتوي على أصول ثابتة (static assets).

مخطط معماري لتطبيق لا خادمي يوضح تفاعل العميل مع حساب تخزين لملفات ثابتة

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

ما هي وظائف Azure (Azure Functions)؟

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

في المعمارية اللا خادمية، إذا أردنا أن يتم تنفيذ جزء من الشيفرة على جانب الخادم، فإننا نستخدم وظيفة Azure Function.

مخطط معماري لتطبيق لا خادمي يستخدم Azure Functions لمعالجة طلبات الواجهة الخلفية

وظائف Azure Functions هي منصة حوسبة لا خادمية تعتمد على الأحداث (event-driven). الميزة الأبرز هي أنك تدفع فقط عند حدوث التنفيذ، مما يجعلها فعالة للغاية من حيث التكلفة. كما أنها سهلة التوسع بشكل طبيعي. وبالتالي، نحصل على فوائد التوسع والتكلفة معًا باستخدام Azure Functions. لمزيد من المعلومات، يمكنك الرجوع إلى الوثائق الرسمية لـ Azure Functions.

لماذا يجب عليك استخدام Azure Serverless؟

يمكن لحلول Azure Serverless أن تضيف قيمة كبيرة لمنتجك من خلال تقليل الوقت والموارد التي تنفقها على المتطلبات المتعلقة بالبنية التحتية. يمكنك زيادة إنتاجية المطورين، وتحسين استخدام الموارد، وتسريع وقت الوصول إلى السوق (time to market) بمساعدة حل Azure Serverless المُدار بالكامل من البداية إلى النهاية. لمعرفة المزيد، راجع الوثائق الرسمية لـ Azure Serverless.

ما هو Blazor؟

Blazor هو إطار عمل ويب من .NET لإنشاء تطبيقات من جانب العميل (client-side applications) باستخدام لغتي C# و Razor بالإضافة إلى HTML. يعمل Blazor في المتصفح بمساعدة تقنية WebAssembly. يمكنه تبسيط عملية إنشاء تطبيقات الصفحة الواحدة (Single Page Application - SPA)، كما يوفر تجربة تطوير ويب متكاملة (full-stack) باستخدام .NET.

استخدام .NET لتطوير تطبيقات من جانب العميل له مزايا متعددة:

  • يقدم .NET مجموعة واسعة من واجهات برمجة التطبيقات (API) والأدوات المستقرة وسهلة الاستخدام عبر جميع المنصات.
  • توفر اللغات الحديثة مثل C# و F# الكثير من الميزات التي تجعل البرمجة أسهل وأكثر إثارة للاهتمام للمطورين.
  • يتيح توفر أحد أفضل بيئات التطوير المتكاملة (IDE) في شكل Visual Studio تجربة تطوير .NET رائعة عبر منصات متعددة مثل Windows و Linux و macOS.
  • يوفر .NET ميزات مثل السرعة والأداء والأمان وقابلية التوسع والموثوقية في تطوير الويب، مما يسهل عملية التطوير المتكامل.

لماذا يجب عليك استخدام Blazor؟

يدعم Blazor مجموعة واسعة من الميزات التي تجعل تطوير الويب أسهل للمطورين. من أبرز هذه الميزات:

  • بنية قائمة على المكونات (Component-based architecture): يوفر Blazor بنية قائمة على المكونات لإنشاء واجهات مستخدم غنية وقابلة للتركيب.
  • حقن التبعية (Dependency injection): يسمح لنا هذا باستخدام الخدمات عن طريق حقنها في المكونات.
  • التخطيطات (Layouts): يمكننا مشاركة عناصر واجهة المستخدم المشتركة (مثل القوائم) عبر الصفحات باستخدام ميزة التخطيطات.
  • التوجيه (Routing): يمكننا إعادة توجيه طلب العميل من مكون إلى آخر بمساعدة التوجيه.
  • التفاعل مع جافاسكريبت (JavaScript interop): يتيح لنا هذا استدعاء دالة C# من JavaScript، ويمكننا استدعاء دالة JavaScript أو واجهة برمجة تطبيقات (API) من شيفرة C#.
  • العولمة والتوطين (Globalization and localization): يمكن جعل التطبيق متاحًا للمستخدمين في ثقافات ولغات متعددة.
  • إعادة التحميل المباشر (Live reloading): إعادة تحميل التطبيق مباشرة في المتصفح أثناء التطوير.
  • النشر (Deployment): يمكننا نشر تطبيق Blazor على IIS و Azure Cloud.

لمعرفة المزيد حول Blazor، يرجى الرجوع إلى الوثائق الرسمية لـ Blazor.

المتطلبات الأساسية

للبدء في تطوير التطبيق، نحتاج إلى توفير المتطلبات الأساسية التالية:

أثناء تثبيت Visual Studio 2019، يرجى التأكد من تحديد أحمال العمل (workloads) الخاصة بـ Azure development و ASP.NET and web development.

لقطة شاشة لخيارات تثبيت Visual Studio 2019 مع تحديد أحمال عمل تطوير Azure و ASP.NET

الشيفرة المصدرية

يمكنك الحصول على الشيفرة المصدرية الكاملة للمشروع من مستودع GitHub عبر الرابط التالي: هنا.

إنشاء حساب Azure Cosmos DB

قم بتسجيل الدخول إلى بوابة Azure وابحث عن “Azure Cosmos DB” في شريط البحث، ثم انقر على النتيجة. في الشاشة التالية، انقر على زر “Add” (إضافة). سيؤدي هذا إلى فتح صفحة “Create Azure Cosmos DB Account” (إنشاء حساب Azure Cosmos DB). ستحتاج إلى ملء المعلومات المطلوبة لإنشاء قاعدة البيانات الخاصة بك. راجع الصورة الموضحة أدناه:

واجهة إنشاء حساب Azure Cosmos DB في بوابة Azure مع حقول الاشتراك ومجموعة الموارد واسم الحساب وواجهة برمجة التطبيقات والموقع

يمكنك ملء التفاصيل على النحو التالي:

  • Subscription (الاشتراك): اختر اسم اشتراك Azure الخاص بك من القائمة المنسدلة.
  • Resource Group (مجموعة الموارد): اختر مجموعة موارد موجودة أو أنشئ واحدة جديدة.
  • Account Name (اسم الحساب): أدخل اسمًا فريدًا لحساب Azure Cosmos DB الخاص بك. يجب أن يحتوي الاسم على أحرف صغيرة وأرقام وعلامة ‘-‘ فقط، وأن يتراوح طوله بين 3 و 44 حرفًا.
  • API: اختر Core (SQL).
  • Location (الموقع): اختر موقعًا لاستضافة حساب Azure Cosmos DB الخاص بك.

احتفظ بالحقول الأخرى بقيمها الافتراضية وانقر على زر “Review + Create” (مراجعة + إنشاء). في الشاشة التالية، راجع جميع إعداداتك ثم انقر على زر “Create” (إنشاء). بعد بضع دقائق، سيتم إنشاء حساب Azure Cosmos DB. انقر على “Go to resource” (الانتقال إلى المورد) للانتقال إلى صفحة حساب Azure Cosmos DB.

إعداد قاعدة البيانات

في صفحة حساب Azure Cosmos DB، انقر على “Data Explorer” (مستكشف البيانات) في قائمة التنقل اليسرى، ثم اختر “New Container” (حاوية جديدة). راجع الصورة الموضحة أدناه:

واجهة مستكشف البيانات في Azure Cosmos DB مع خيار إنشاء حاوية جديدة

ستفتح لوحة “Add Container” (إضافة حاوية). ستحتاج إلى ملء التفاصيل لإنشاء حاوية جديدة لـ Azure Cosmos DB الخاص بك. راجع الصورة الموضحة أدناه:

واجهة إضافة حاوية جديدة في Azure Cosmos DB مع حقول معرف قاعدة البيانات ومعرف الحاوية ومفتاح التقسيم

يمكنك ملء التفاصيل كما هو موضح أدناه:

  • Database ID (معرف قاعدة البيانات): يمكنك إعطاء أي اسم لقاعدة البيانات الخاصة بك. هنا، نستخدم FAQDB.
  • Throughput (الإنتاجية): احتفظ بها بالقيمة الافتراضية 400.
  • Container ID (معرف الحاوية): أدخل اسمًا لحاويتك. هنا، نستخدم FAQContainer.
  • Partition key (مفتاح التقسيم): يُستخدم مفتاح التقسيم لتقسيم البيانات تلقائيًا بين خوادم متعددة لتحقيق قابلية التوسع. ضع القيمة كـ “/id“.

انقر على زر “OK” (موافق) لإنشاء قاعدة البيانات.

إضافة بيانات نموذجية إلى Cosmos DB

في مستكشف البيانات (Data Explorer)، قم بتوسيع قاعدة البيانات FAQDB ثم توسيع FAQContainer. اختر Items (العناصر)، ثم انقر على New Item (عنصر جديد) في الأعلى. سيتم فتح محرر على الجانب الأيمن من الصفحة. راجع الصورة الموضحة أدناه:

واجهة إضافة عنصر جديد في مستكشف بيانات Azure Cosmos DB لتحرير بيانات JSON

ضع بيانات JSON التالية في المحرر وانقر على زر “Save” (حفظ) في الأعلى.

{ "id" : "1" , "question" : "What is corona virus?" , "answer" : "Corona viruses are a large family of viruses which may cause illness in animals or humans. The most recently discovered coronavirus causes coronavirus disease COVID-19." }

لقد أضفنا مجموعة من الأسئلة والأجوبة مع معرف فريد (unique id). اتبع العملية الموضحة أعلاه لإدراج خمس مجموعات أخرى من البيانات.

{ "id" : "2" , "question" : "What is COVID-19?" , "answer" : "COVID-19 is the infectious disease caused by the most recently discovered corona virus. This new virus and disease were unknown before the outbreak began in Wuhan, China, in December 2019." } { "id" : "3" , "question" : "What are the symptoms of COVID-19?" , "answer" : "The most common symptoms of COVID-19 are fever, tiredness, and dry cough. Some patients may have aches and pains, nasal congestion, runny nose, sore throat or diarrhea. These symptoms are usually mild and begin gradually. Some people become infected but don’t develop any symptoms and don't feel unwell." } { "id" : "4" , "question" : "How does COVID-19 spread?" , "answer" : "People can catch COVID-19 from others who have the virus. The disease can spread from person to person through small droplets from the nose or mouth which are spread when a person with COVID-19 coughs or exhales. These droplets land on objects and surfaces around the person. Other people then catch COVID-19 by touching these objects or surfaces, then touching their eyes, nose or mouth." } { "id" : "5" , "question" : "What can I do to protect myself and prevent the spread of disease?" , "answer" : "You can reduce your chances of being infected or spreading COVID-19 by taking some simple precaution. Regularly and thoroughly clean your hands with an alcoholbased hand rub or wash them with soap and water. Maintain at least 1 metre (3 feet) distance between yourself and anyone who is coughing or sneezing. Make sure you, and the people around you, follow good respiratory hygiene. This means covering your mouth and nose with your bent elbow or tissue when you cough or sneeze. Stay home if you feel unwell. If you have a fever, cough and difficulty breathing, seek medical attention and call in advance." } { "id" : "6" , "question" : "Are antibiotics effective in preventing or treating the COVID-19?" , "answer" : "No. Antibiotics do not work against viruses, they only work on bacterial infections. COVID-19 is caused by a virus, so antibiotics do not work." }

الحصول على سلسلة الاتصال (Connection String)

انقر على “Keys” (المفاتيح) في قائمة التنقل اليسرى، ثم انتقل إلى علامة التبويب “Read-write Keys” (مفاتيح القراءة والكتابة). القيمة الموجودة تحت PRIMARY CONNECTION STRING هي سلسلة الاتصال المطلوبة. راجع الصورة الموضحة أدناه:

صفحة مفاتيح Azure Cosmos DB تظهر سلسلة الاتصال الأساسية للقراءة والكتابة

قم بتدوين قيمة PRIMARY CONNECTION STRING. سنستخدمها في الجزء الأخير من هذا المقال، عندما نصل إلى Azure Cosmos DB من خلال دالة Azure Function.

إنشاء تطبيق وظائف Azure (Azure Function App)

افتح Visual Studio 2019، وانقر على “Create a new project” (إنشاء مشروع جديد). ابحث عن “Functions” في مربع البحث. اختر قالب Azure Functions وانقر على “Next” (التالي). راجع الصورة الموضحة أدناه:

واجهة إنشاء مشروع جديد في Visual Studio 2019 مع البحث عن قوالب Azure Functions

في نافذة “Configure your new project” (تكوين مشروعك الجديد)، أدخل اسم المشروع كـ FAQFunctionApp. انقر على زر “Create” (إنشاء). راجع الصورة أدناه:

واجهة تكوين مشروع Azure Functions الجديد مع حقل اسم المشروع FAQFunctionApp

ستفتح نافذة جديدة بعنوان “Create a new Azure Function Application settings” (إنشاء إعدادات تطبيق وظائف Azure جديد). اختر “Azure Functions v3 (.NET Core)” من القائمة المنسدلة في الأعلى. اختر قالب الدالة كـ “HTTP trigger“. اضبط مستوى المصادقة (authorization level) على “Anonymous” من القائمة المنسدلة على اليمين. انقر على زر “Create” (إنشاء) لإنشاء مشروع الدالة ودالة HTTP trigger. راجع الصورة الموضحة أدناه:

واجهة إعدادات تطبيق Azure Function جديد مع اختيار Azure Functions v3 و HTTP trigger ومستوى المصادقة Anonymous

تثبيت حزمة Azure Cosmos DB

لتمكين تطبيق وظائف Azure Function App من الارتباط بـ Azure Cosmos DB، نحتاج إلى تثبيت حزمة Microsoft.Azure.WebJobs.Extensions.CosmosDB. انتقل إلى Tools >> NuGet Package Manager >> Package Manager Console وقم بتشغيل الأمر التالي:

Install-Package Microsoft.Azure.WebJobs.Extensions.CosmosDB

راجع الصورة الموضحة أدناه.

وحدة تحكم مدير حزم NuGet في Visual Studio تعرض أمر تثبيت حزمة Microsoft.Azure.WebJobs.Extensions.CosmosDB

يمكنك معرفة المزيد عن هذه الحزمة في معرض NuGet.

تكوين تطبيق وظائف Azure

يحتوي مشروع وظائف Azure Function على ملف افتراضي يسمى Function1.cs. يمكنك حذف هذا الملف بأمان لأننا لن نستخدمه في مشروعنا. انقر بزر الماوس الأيمن على مشروع FAQFunctionApp واختر Add >> New Folder. سمِّ المجلد Models. مرة أخرى، انقر بزر الماوس الأيمن على مجلد Models واختر Add >> Class لإضافة ملف فئة جديد. ضع اسم الفئة FAQ.cs وانقر على Add. افتح FAQ.cs وضع الشيفرة التالية بداخله.

namespace FAQFunctionApp.Models
{
    class FAQ
    {
        public string Id { get; set; }
        public string Question { get; set; }
        public string Answer { get; set; }
    }
}

تحتوي الفئة على نفس البنية مثل بيانات JSON التي أدرجناها في Cosmos DB. انقر بزر الماوس الأيمن على مشروع FAQFunctionApp واختر Add >> Class. سمِّ الفئة CovidFAQ.cs. ضع الشيفرة التالية بداخله.

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs;
using FAQFunctionApp.Models;
using Microsoft.Azure.WebJobs.Extensions.Http;
using System.Threading.Tasks;

namespace FAQFunctionApp
{
    class CovidFAQ
    {
        [FunctionName("covidFAQ")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
            [CosmosDB(
                databaseName: "FAQDB",
                collectionName: "FAQContainer",
                ConnectionStringSetting = "DBConnectionString")] IEnumerable<FAQ> questionSet,
            ILogger log)
        {
            log.LogInformation("Data fetched from FAQContainer");
            return new OkObjectResult(questionSet);
        }
    }
}

لقد أنشأنا فئة باسم CovidFAQ وأضفنا دالة Azure Function إليها. تُستخدم السمة FunctionName لتحديد اسم الدالة. استخدمنا السمة HttpTrigger التي تسمح بتشغيل الدالة عبر استدعاء HTTP. تُستخدم السمة CosmosDB للاتصال بـ Azure Cosmos DB. لقد حددنا ثلاثة معلمات لهذه السمة كما هو موضح أدناه:

  • databaseName: اسم قاعدة بيانات Cosmos DB.
  • collectionName: المجموعة داخل Cosmos DB التي نريد الوصول إليها.
  • ConnectionStringSetting: سلسلة الاتصال للاتصال بـ Cosmos DB. سنقوم بتكوينها في القسم التالي.

لقد زيّنا المعلمة questionSet، وهي من النوع IEnumerable<FAQ>، بسمة CosmosDB. عند تنفيذ التطبيق، سيتم ملء المعلمة questionSet بالبيانات من Cosmos DB. ستقوم الدالة بإرجاع البيانات باستخدام مثيل جديد من OkObjectResult.

إضافة سلسلة الاتصال إلى دالة Azure

هل تتذكر سلسلة اتصال Azure Cosmos DB التي دونتها سابقًا؟ الآن سنقوم بتكوينها لتطبيقنا. افتح ملف local.settings.json وأضف سلسلة الاتصال الخاصة بك كما هو موضح أدناه:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "DBConnectionString": "your connectionn string"
  }
}

لن يتم نشر ملف local.settings.json إلى Azure عند نشر تطبيق وظائف Azure Function app. لذلك، نحتاج إلى تكوين سلسلة الاتصال بشكل منفصل أثناء نشر التطبيق إلى Azure. سنرى هذا عمليًا في الجزء الأخير من هذا المقال.

اختبار دالة Azure محليًا

اضغط على F5 لتنفيذ الدالة. انسخ عنوان URL الخاص بالدالة من مخرجات وقت تشغيل Azure Functions. راجع الصورة الموضحة أدناه:

مخرجات وقت تشغيل Azure Functions في Visual Studio تعرض عنوان URL للدالة المحلية

افتح المتصفح والصق عنوان URL في شريط عنوان المتصفح. يمكنك رؤية المخرجات كما هو موضح أدناه:

نتائج تشغيل دالة Azure محليًا في المتصفح تعرض بيانات الأسئلة الشائعة بصيغة JSON

هنا يمكنك رؤية البيانات التي أدرجناها في Azure Cosmos DB الخاص بنا.

نشر تطبيق الوظائف إلى Azure

لقد أنشأنا تطبيق الوظائف بنجاح، ولكنه لا يزال يعمل على الجهاز المحلي (localhost). دعنا ننشر التطبيق لجعله متاحًا عالميًا. انقر بزر الماوس الأيمن على مشروع FAQFunctionApp واختر Publish. اختر هدف النشر كـ Azure.

واجهة نشر مشروع Azure Functions مع تحديد هدف النشر كـ Azure

اختر الهدف المحدد كـ “Azure Function App (windows)“.

واجهة نشر مشروع Azure Functions مع تحديد الهدف المحدد كـ Azure Function App (Windows)

في النافذة التالية، انقر على زر “Create a new Azure Function…” (إنشاء دالة Azure جديدة…). ستفتح نافذة تطبيق وظائف جديدة. راجع الصورة كما هو موضح أدناه:

واجهة إنشاء تطبيق وظائف جديد في Azure مع حقول الاسم والاشتراك ومجموعة الموارد ونوع الخطة والموقع

يمكنك ملء التفاصيل كما هو موضح أدناه:

  • Name (الاسم): اسم فريد عالميًا لتطبيق الوظائف الخاص بك.
  • Subscription (الاشتراك): اختر اسم اشتراك Azure الخاص بك من القائمة المنسدلة.
  • Resource Group (مجموعة الموارد): اختر مجموعة موارد موجودة أو أنشئ واحدة جديدة.
  • Plan Type (نوع الخطة): اختر Consumption. سيضمن ذلك أنك تدفع فقط مقابل عمليات تنفيذ تطبيق الوظائف الخاص بك.
  • Location (الموقع): اختر موقعًا لدالتك.
  • Azure Storage (تخزين Azure): احتفظ بالقيمة الافتراضية.

انقر على زر “Create” (إنشاء) لإنشاء تطبيق الوظائف والعودة إلى النافذة السابقة. تأكد من تحديد خيار “Run from package file” (التشغيل من ملف الحزمة). انقر على زر “Finish” (إنهاء).

واجهة نشر مشروع Azure Functions مع خيار التشغيل من ملف حزمة محدد

الآن أنت في صفحة النشر. انقر على زر “Manage Azure App Service Settings” (إدارة إعدادات خدمة تطبيق Azure).

زر إدارة إعدادات Azure App Service في واجهة النشر

سترى نافذة “Application Settings” (إعدادات التطبيق) كما هو موضح أدناه:

نافذة إعدادات التطبيق في Azure لتعيين سلسلة الاتصال DBConnectionString

في هذه المرحلة، سنقوم بتكوين القيمة البعيدة (Remote value) لمفتاح “DBConnectionString“. تُستخدم هذه القيمة عند نشر التطبيق على Azure. نظرًا لأن المفتاح لبيئتي التطوير المحلية والبعيدة هو نفسه في حالتنا، انقر على زر “Insert value from Local” (إدراج قيمة من المحلي) لنسخ القيمة من الحقل المحلي إلى الحقل البعيد. انقر على زر “OK” (موافق). ستعود إلى صفحة النشر. لقد انتهينا من جميع التكوينات. انقر على زر “Publish” (نشر) لنشر تطبيق وظائف Azure الخاص بك.

بعد نشر التطبيق، احصل على قيمة site URL، وألحق بها /api/covidFAQ وافتحها في المتصفح. يمكنك رؤية المخرجات كما هو موضح أدناه.

نتائج تشغيل دالة Azure المنشورة عالميًا في المتصفح تعرض بيانات الأسئلة الشائعة بصيغة JSON

هذه هي نفس مجموعة البيانات التي حصلنا عليها أثناء تشغيل التطبيق محليًا. هذا يثبت أن دالة Azure اللا خادمية الخاصة بنا تم نشرها وتستطيع الوصول إلى Azure Cosmos DB بنجاح.

تمكين CORS لخدمة تطبيق Azure

سنستخدم تطبيق الوظائف في مشروع واجهة مستخدم Blazor. للسماح لتطبيق Blazor بالوصول إلى دالة Azure Function، نحتاج إلى تمكين CORS (مشاركة الموارد عبر المنشأ) لخدمة تطبيق Azure. افتح بوابة Azure. انتقل إلى “All resources” (جميع الموارد). هنا، يمكنك رؤية خدمة التطبيق (App service) التي أنشأناها أثناء نشر التطبيق في القسم السابق. انقر على المورد للانتقال إلى صفحة المورد. انقر على CORS في قائمة التنقل اليسرى. ستفتح لوحة تفاصيل CORS. الآن لدينا خياران هنا:

  • إدخال عنوان URL للمنشأ المحدد للسماح له بإجراء استدعاءات عبر المنشأ.
  • إزالة جميع عناوين URL للمنشأ من القائمة، واستخدام رمز البدل “*” للسماح لجميع عناوين URL بإجراء استدعاءات عبر المنشأ.

سنستخدم الخيار الثاني لتطبيقنا. قم بإزالة جميع عناوين URL المدرجة مسبقًا وأدخل إدخالًا واحدًا كرمز البدل “*“. انقر على زر “Save” (حفظ) في الأعلى. راجع الصورة الموضحة أدناه:

واجهة إعدادات CORS في Azure App Service مع السماح لجميع المصادر باستخدام الرمز النجمي (*)

إنشاء مشروع Blazor WebAssembly

افتح Visual Studio 2019، انقر على “Create a new project” (إنشاء مشروع جديد). اختر “Blazor App” وانقر على زر “Next” (التالي). راجع الصورة الموضحة أدناه:

واجهة إنشاء مشروع جديد في Visual Studio 2019 مع تحديد قالب Blazor App

في نافذة “Configure your new project” (تكوين مشروعك الجديد)، ضع اسم المشروع كـ FAQUIApp وانقر على زر “Create” (إنشاء) كما هو موضح في الصورة أدناه:

واجهة تكوين مشروع Blazor الجديد مع حقل اسم المشروع FAQUIApp

في نافذة “Create a new Blazor app” (إنشاء تطبيق Blazor جديد)، اختر قالب “Blazor WebAssembly App“. انقر على زر “Create” (إنشاء) لإنشاء المشروع. راجع الصورة الموضحة أدناه:

واجهة إنشاء تطبيق Blazor جديد مع تحديد قالب Blazor WebAssembly App

لإنشاء مكون Razor جديد، انقر بزر الماوس الأيمن على مجلد Pages، واختر Add >> Razor Component. سيتم فتح مربع حوار “Add New Item” (إضافة عنصر جديد)، ضع اسم المكون كـ CovidFAQ.razor وانقر على زر “Add” (إضافة). راجع الصورة الموضحة أدناه:

مربع حوار إضافة عنصر جديد في Visual Studio لإنشاء مكون Razor باسم CovidFAQ.razor

افتح CovidFAQ.razor وضع الشيفرة التالية بداخله.

@page "/covidfaq"
@inject HttpClient Http

<div class="d-flex justify-content-center">
    <img src="../Images/COVID_banner.jpg" alt="Image" style="width:80%; height:300px" />
</div>
<br />
<div class="d-flex justify-content-center">
    <h1>Frequently asked Questions on Covid-19</h1>
</div>
<hr />

@if (questionList == null)
{
    <p><em>Loading...</em></p>
}
else
{
    @foreach (var question in questionList)
    {
        <div class="card">
            <h3 class="card-header">@question.Question</h3>
            <div class="card-body">
                <p class="card-text">@question.Answer</p>
            </div>
        </div>
        <br />
    }
}

@code {
    private FAQ[] questionList;

    protected override async Task OnInitializedAsync()
    {
        questionList = await Http.GetFromJsonAsync<FAQ[]>("https://faqfunctionapp20200611160123.azurewebsites.net/api/covidFAQ");
    }

    public class FAQ
    {
        public string Id { get; set; }
        public string Question { get; set; }
        public string Answer { get; set; }
    }
}

في قسم @code، أنشأنا فئة تسمى FAQ. هيكل هذه الفئة هو نفسه هيكل فئة FAQ التي أنشأناها سابقًا في تطبيق دالة Azure Function app. داخل الدالة OnInitializedAsync، نقوم باستدعاء نقطة نهاية API لتطبيق وظائفنا. سيتم تخزين البيانات التي تم إرجاعها من API في متغير يسمى questionList وهو مصفوفة من النوع FAQ. في قسم HTML من الصفحة، قمنا بتعيين صورة بانر في أعلى الصفحة. الصورة متاحة في مجلد /wwwroot/Images. سنستخدم حلقة foreach للتكرار عبر مصفوفة questionList وإنشاء بطاقة bootstrap لعرض السؤال والإجابة.

إضافة رابط إلى قائمة التنقل

الخطوة الأخيرة هي إضافة رابط مكون CovidFAQ الخاص بنا في قائمة التنقل. افتح ملف /Shared/NavMenu.razor وأضف الشيفرة التالية بداخله.

<li class="nav-item px-3">
    <NavLink class="nav-link" href="covidfaq">
        <span class="oi oi-plus" aria-hidden="true"></span> Covid FAQ
    </NavLink>
</li>

يمكنك إزالة روابط التنقل لمكوني Counter و Fetch-data لأنهما غير مطلوبين لهذا التطبيق.

عرض التنفيذ

اضغط على F5 لتشغيل التطبيق. انقر على زر Covid FAQ في قائمة التنقل على اليسار. يمكنك رؤية جميع الأسئلة والأجوبة في تصميم بطاقات جميل كما هو موضح أدناه:

لقطة شاشة لتطبيق الأسئلة الشائعة حول COVID-19 المبني باستخدام Blazor WebAssembly يعرض الأسئلة والأجوبة في بطاقات

يمكنك أيضًا التحقق من التطبيق المباشر على الرابط: https://covid19-faq.azurewebsites.net/.

الخلاصة التقنية

في هذا المقال، استعرضنا بعمق مفهوم المعمارية اللا خادمية ومزاياها الكبيرة مقارنة بمعمارية الويب التقليدية ثلاثية الطبقات. لقد تعلمنا كيف تتكامل وظائف Azure Functions ببراعة ضمن المعمارية اللا خادمية لتوفير حلول حوسبة فعالة ومرنة. لتجسيد هذه المفاهيم، قمنا ببناء تطبيق أسئلة متكررة حول Covid-19 باستخدام Blazor WebAssembly وخدمات Azure Serverless. استخدمنا Azure Cosmos DB كقاعدة بيانات أساسية لتخزين الأسئلة والأجوبة، ووظيفة Azure Function لجلب هذه البيانات. تم نشر تطبيق الوظائف على Azure لجعله متاحًا عالميًا عبر نقطة نهاية API، مما سمح لتطبيق Blazor بواجهة المستخدم بعرض البيانات بشكل ديناميكي وجذاب باستخدام تصميم البطاقات من Bootstrap. يبرهن هذا المشروع على قوة وفعالية دمج هذه التقنيات لإنشاء تطبيقات ويب حديثة قابلة للتوسع وذات تكلفة تشغيلية منخفضة.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *