كيفية بناء تطبيقات لا خادمية باستخدام Azure Functions و Blazor WebAssembly
مقدمة في بناء التطبيقات اللا خادمية باستخدام 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 هي منصة حوسبة لا خادمية تعتمد على الأحداث (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.
المتطلبات الأساسية
للبدء في تطوير التطبيق، نحتاج إلى توفير المتطلبات الأساسية التالية:
- حساب اشتراك في
Azure. يمكنك إنشاء حسابAzureمجاني من خلال الرابط: https://azure.microsoft.com/en-in/free/. - تثبيت أحدث إصدار من
Visual Studio 2019من الرابط: https://visualstudio.microsoft.com/downloads/.
أثناء تثبيت Visual Studio 2019، يرجى التأكد من تحديد أحمال العمل (workloads) الخاصة بـ Azure development و ASP.NET and web development.

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

يمكنك ملء التفاصيل على النحو التالي:
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” (حاوية جديدة). راجع الصورة الموضحة أدناه:

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

يمكنك ملء التفاصيل كما هو موضح أدناه:
Database ID(معرف قاعدة البيانات): يمكنك إعطاء أي اسم لقاعدة البيانات الخاصة بك. هنا، نستخدمFAQDB.Throughput(الإنتاجية): احتفظ بها بالقيمة الافتراضية 400.Container ID(معرف الحاوية): أدخل اسمًا لحاويتك. هنا، نستخدمFAQContainer.Partition key(مفتاح التقسيم): يُستخدم مفتاح التقسيم لتقسيم البيانات تلقائيًا بين خوادم متعددة لتحقيق قابلية التوسع. ضع القيمة كـ “/id“.
انقر على زر “OK” (موافق) لإنشاء قاعدة البيانات.
إضافة بيانات نموذجية إلى Cosmos DB
في مستكشف البيانات (Data Explorer)، قم بتوسيع قاعدة البيانات FAQDB ثم توسيع FAQContainer. اختر Items (العناصر)، ثم انقر على New Item (عنصر جديد) في الأعلى. سيتم فتح محرر على الجانب الأيمن من الصفحة. راجع الصورة الموضحة أدناه:

ضع بيانات 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 هي سلسلة الاتصال المطلوبة. راجع الصورة الموضحة أدناه:

قم بتدوين قيمة PRIMARY CONNECTION STRING. سنستخدمها في الجزء الأخير من هذا المقال، عندما نصل إلى Azure Cosmos DB من خلال دالة Azure Function.
إنشاء تطبيق وظائف Azure (Azure Function App)
افتح Visual Studio 2019، وانقر على “Create a new project” (إنشاء مشروع جديد). ابحث عن “Functions” في مربع البحث. اختر قالب Azure Functions وانقر على “Next” (التالي). راجع الصورة الموضحة أدناه:

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

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

تثبيت حزمة 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.
تكوين تطبيق وظائف 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. راجع الصورة الموضحة أدناه:

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

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

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

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

يمكنك ملء التفاصيل كما هو موضح أدناه:
Name(الاسم): اسم فريد عالميًا لتطبيق الوظائف الخاص بك.Subscription(الاشتراك): اختر اسم اشتراكAzureالخاص بك من القائمة المنسدلة.Resource Group(مجموعة الموارد): اختر مجموعة موارد موجودة أو أنشئ واحدة جديدة.Plan Type(نوع الخطة): اخترConsumption. سيضمن ذلك أنك تدفع فقط مقابل عمليات تنفيذ تطبيق الوظائف الخاص بك.Location(الموقع): اختر موقعًا لدالتك.Azure Storage(تخزينAzure): احتفظ بالقيمة الافتراضية.
انقر على زر “Create” (إنشاء) لإنشاء تطبيق الوظائف والعودة إلى النافذة السابقة. تأكد من تحديد خيار “Run from package file” (التشغيل من ملف الحزمة). انقر على زر “Finish” (إنهاء).

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

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

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

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

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

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

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

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

افتح 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 في قائمة التنقل على اليسار. يمكنك رؤية جميع الأسئلة والأجوبة في تصميم بطاقات جميل كما هو موضح أدناه:

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