هل تعلم أن تطبيق 'مطعمDelivery' في الإسكندرية، ومنصة 'حجز تذاكر الأهرامات' الشهيرة، و'موقع مكتبة الإسكندرية' الرقمي، كلها تستخدم في خلفيتها تقنية Node.js مع Express.js؟ في مصر، حيث يتزايد الاعتماد على الحلول الرقمية - من المطاعم الصغيرة إلى الشركات الكبرى - أصبحت مهارة بناء خوادم ويب سريعة وآمنة باستخدام Express.js من المهارات الأساسية لخريج الثانوية العامة في التخصصات الهندسية والتكنولوجية. في هذا الامتحان، لن نختبر فقط معرفتك بالنظريات، بل سنجعلك تطبقها على سيناريوهات حقيقية من حياتنا اليومية: من إنشاء API يعرض أسعار تذاكر المتاحف، إلى نظام تسجيل دخول بسيط لتطبيق سياحي. استعد، فلنبدأ!
إنشاء خادم ويب بسيط لعرض معلومات عن الأهرامات (2 points)
في مشروعك لمتحف الجيزة، تحتاج إلى إنشاء خادم ويب بسيط يعرض معلومات أساسية عن الأهرامات. يجب أن يستجيب الخادم لطلبات GET على المسار الرئيسي ويعيد رسالة ترحيبية.
- المنفذ (port) = 3000
- رسالة الترحيب: 'مرحبا بكم في متحف الأهرامات - معرض الجيزة'
- اكتب الكود الكامل لخادم Express.js الذي يستجيب لطلبات GET على المسار '/' ويعيد الرسالة المحددة.
- ما هو الأمر الذي ستكتبه في الطرفية لتشغيل هذا الخادم؟
- كيف تختبر أن الخادم يعمل بشكل صحيح؟ (اذكر رابط الاختبار)
الحل الكامل
السؤال 1 (1 نقاط) — اكتب الكود الكامل لخادم Express.js الذي يستجيب لطلبات GET على المسار '/' ويعيد الرسالة المحددة.
- الاستيراد وإنشاء التطبيق — استخدم const express = require('express'); لإنشاء تطبيق Express باستخدام const app = express();
- تعريف المسار GET — استخدم app.get('/', (req, res) => { res.send('مرحبا بكم في متحف الأهرامات - معرض الجيزة'); }); لتعريف المسار الرئيسي.
- تشغيل الخادم — استخدم app.listen(3000, () => { console.log('الخادم يعمل على http://localhost:3000'); }); لتشغيل الخادم.
← الكود الكامل: const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('مرحبا بكم في متحف الأهرامات - معرض الجيزة'); }); app.listen(3000, () => { console.log('الخادم يعمل على http://localhost:3000'); });
السؤال 2 (0 نقاط) — ما هو الأمر الذي ستكتبه في الطرفية لتشغيل هذا الخادم؟
- أمر التشغيل — اكتب في الطرفية команду node app.js لتشغيل الخادم. تأكد من أنك داخل مجلد المشروع.
← node app.js
السؤال 3 (1 نقاط) — كيف تختبر أن الخادم يعمل بشكل صحيح؟ (اذكر رابط الاختبار)
- اختبار الخادم — افتح متصفحك واكتب الرابط http://localhost:3000 ثم اضغط على Enter. يجب أن تظهر الرسالة 'مرحبا بكم في متحف الأهرامات - معرض الجيزة'.
سلم التقدير
| الكود يعمل ويعيد الرسالة الصحيحة | 1 نقاط |
| الأمر الصحيح لتشغيل الخادم | 0 نقاط |
| طريقة الاختبار الصحيحة (رابط المتصفح) | 1 نقاط |
تصميم API لعرض معلومات المدن المصرية (3 points)
أنت مطور في شركة سياحية مصرية، وطلب منك إنشاء API بسيط يعرض معلومات عن المدن السياحية الرئيسية: القاهرة، الإسكندرية، الأقصر، وأسوان. يجب أن يستجيب API لطلبات GET على المسارات المناسبة ويعيد البيانات بتنسيق JSON.
- القاهرة: { "id": 1, "name": "القاهرة", "population": 10000000, "famou": "الأهرامات" }
- الإسكندرية: { "id": 2, "name": "الإسكندرية", "population": 5000000, "famou": "مكتبة الإسكندرية" }
- الأقصر: { "id": 3, "name": "الأقصر", "population": 1500000, "famou": "معبد الكرنك" }
- أسوان: { "id": 4, "name": "أسوان", "population": 1000000, "famou": "السد العالي" }
- اكتب الكود الكامل لإنشاء API يعرض جميع المدن.
- اكتب الكود لإنشاء مسار يعرض معلومات مدينة محددة حسب المعرف (id).
- كيف تختبر المسار /cities/2 في المتصفح؟ اذكر الرابط الكامل.
الحل الكامل
السؤال 1 (1 نقاط) — اكتب الكود الكامل لإنشاء API يعرض جميع المدن.
- استيراد التبعيات — استخدم const express = require('express'); لإنشاء تطبيق Express.
- تعريف البيانات — قم بتعريف مصفوفة cities تحتوي على البيانات الأربع للمدن.
- تعريف المسار GET /cities — استخدم app.get('/cities', (req, res) => { res.json(cities); }); لإرجاع جميع المدن بتنسيق JSON.
← الكود الكامل: const express = require('express'); const app = express(); const cities = [ { id: 1, name: "القاهرة", population: 10000000, famou: "الأهرامات" }, { id: 2, name: "الإسكندرية", population: 5000000, famou: "مكتبة الإسكندرية" }, { id: 3, name: "الأقصر", population: 1500000, famou: "معبد الكرنك" }, { id: 4, name: "أسوان", population: 1000000, famou: "السد العالي" } ]; app.get('/cities', (req, res) => { res.json(cities); }); app.listen(3000, () => { console.log('الخادم يعمل على http://localhost:3000'); });
السؤال 2 (1 نقاط) — اكتب الكود لإنشاء مسار يعرض معلومات مدينة محددة حسب المعرف (id).
- تعريف المسار الديناميكي — استخدم app.get('/cities/:id', (req, res) => { ... }) لمعالجة المعرف المرسل في المسار.
- البحث في المصفوفة — استخدم const city = cities.find(c => c.id == req.params.id); للبحث عن المدينة التي تطابق المعرف.
- الإرجاع أو الخطأ — إذا وجدت المدينة، ارجعها بتنسيق JSON باستخدام res.json(city). وإلا، ارجع رسالة خطأ باستخدام res.status(404).json({ error: 'المدينة غير موجودة' });
← الكود: app.get('/cities/:id', (req, res) => { const city = cities.find(c => c.id == req.params.id); if (city) { res.json(city); } else { res.status(404).json({ error: 'المدينة غير موجودة' }); } });
السؤال 3 (1 نقاط) — كيف تختبر المسار /cities/2 في المتصفح؟ اذكر الرابط الكامل.
- اختبار المسار — افتح المتصفح واكتب الرابط http://localhost:3000/cities/2 ثم اضغط على Enter. يجب أن تظهر معلومات الإسكندرية.
سلم التقدير
| الكود يعرض جميع المدن بشكل صحيح بتنسيق JSON | 1 نقاط |
| الكود يعرض مدينة محددة حسب المعرف بشكل صحيح | 1 نقاط |
| الرابط الصحيح لاختبار مدينة الإسكندرية | 1 نقاط |
استخدام middleware لتسجيل الطلبات (3 points)
في تطبيقك السياحي، تريد تسجيل جميع الطلبات التي تصل إلى API الخاص بك (مثل طلبات الحصول على معلومات المدن) في ملف سجل (log file) لحل المشاكل later. يجب إنشاء middleware تقوم بذلك قبل معالجة أي مسار.
- المنفذ: 3000
- مسار API: /api/*
- اكتب الكودMiddleware لتسجيل الطلبات في ملف log.txt.
- كيف تضيف هذا Middleware إلى تطبيق Express.js؟
- ما هو الأمر الذي ستستخدمه لتشغيل الخادم؟
الحل الكامل
السؤال 1 (1 نقاط) — اكتب الكودMiddleware لتسجيل الطلبات في ملف log.txt.
- استيراد fs — استخدم const fs = require('fs'); لاستيراد مكتبة filesystem.
- إنشاء Middleware — اكتب الدالة middleware التالية:
const logRequest = (req, res, next) => {
const log =
[${new Date().toISOString()}] ${req.method} ${req.url}\n; fs.appendFileSync('log.txt', log); next(); };
← الكود:
const fs = require('fs');
const logRequest = (req, res, next) => {
const log = [${new Date().toISOString()}] ${req.method} ${req.url}\n;
fs.appendFileSync('log.txt', log);
next();
};
السؤال 2 (1 نقاط) — كيف تضيف هذا Middleware إلى تطبيق Express.js؟
- إضافة Middleware للتطبيق — استخدم app.use(logRequest); لإضافة middleware إلى جميع المسارات. يمكنك أيضا تحديد المسار باستخدام app.use('/api', logRequest); لتطبيقها فقط على المسارات التي تبدأ بـ /api.
← app.use(logRequest); // لجميع المسارات أو app.use('/api', logRequest); // للمسارات التي تبدأ بـ /api
السؤال 3 (1 نقاط) — ما هو الأمر الذي ستستخدمه لتشغيل الخادم؟
- تشغيل الخادم — اكتب في الطرفية node app.js لتشغيل الخادم. تأكد من أنك داخل مجلد المشروع.
← node app.js
سلم التقدير
| الكودMiddleware يسجل الطلبات بشكل صحيح في ملف log.txt | 1 نقاط |
| إضافة Middleware إلى التطبيق بشكل صحيح | 1 نقاط |
| الأمر الصحيح لتشغيل الخادم | 1 نقاط |
إنشاء API لعرض أسعار تذاكر المتاحف المصرية (4 points)
أنت مطور في وزارة الآثار المصرية، وطلب منك إنشاء API بسيط يعرض أسعار تذاكر الدخول للمتاحف المصرية الشهيرة. يجب أن يستجيب API لطلبات GET على المسار /tickets ويعيد البيانات بتنسيق JSON. سعر تذكرة الطالب 5 جنيهات، وسعر تذكرة البالغ 50 جنيهًا.
- المتاحف: المتحف المصري (القاهرة)، المتحف القبطي (القاهرة)، متحف النوبة (أسوان)
- أسعار التذاكر: طلاب 5 جنيه، بالغون 50 جنيه
- اكتب الكود الكامل لإنشاء API يعرض جميع أسعار التذاكر.
- كيف تختبر أن API يعمل بشكل صحيح؟ اذكر الرابط الذي ستستخدمه.
- ماذا يجب أن تفعل إذا طلب منك إضافة سعر تذكرة الطفل (10 جنيهات)؟ اشرح التعديلات اللازمة.
الحل الكامل
السؤال 1 (2 نقاط) — اكتب الكود الكامل لإنشاء API يعرض جميع أسعار التذاكر.
- استيراد التبعيات — استخدم const express = require('express'); لإنشاء تطبيق Express.
- تعريف البيانات — قم بتعريف مصفوفة museums تحتوي على أسماء المتاحف وأسعار التذاكر لكل فئة.
- تعريف المسار GET /tickets — استخدم app.get('/tickets', (req, res) => { res.json(museums); }); لإرجاع جميع البيانات بتنسيق JSON.
← الكود الكامل: const express = require('express'); const app = express(); const museums = [ { name: "المتحف المصري", studen: 5, adul: 50 }, { name: "المتحف القبطي", studen: 5, adul: 50 }, { name: "متحف النوبة", studen: 5, adul: 50 } ]; app.get('/tickets', (req, res) => { res.json(museums); }); app.listen(3000, () => { console.log('الخادم يعمل على http://localhost:3000'); });
السؤال 2 (1 نقاط) — كيف تختبر أن API يعمل بشكل صحيح؟ اذكر الرابط الذي ستستخدمه.
- اختبار API — افتح المتصفح واكتب الرابط http://localhost:3000/tickets ثم اضغط على Enter. يجب أن تظهر البيانات بتنسيق JSON.
السؤال 3 (1 نقاط) — ماذا يجب أن تفعل إذا طلب منك إضافة سعر تذكرة الطفل (10 جنيهات)؟ اشرح التعديلات اللازمة.
- إضافة فئة جديدة — قم بتعديل الكائن الذي يمثل المتحف بإضافة خاصية chil: 10. ثم أعد تشغيل الخادم. لا حاجة لتعديل المسار لأن البيانات ستُعاد تلقائيا بتنسيق JSON.
← قم بتعديل الكائن: { name: "المتحف المصري", studen: 5, adul: 50, chil: 10 }
سلم التقدير
| الكود يعرض جميع المتاحف وأسعار التذاكر بشكل صحيح بتنسيق JSON | 2 نقاط |
| الرابط الصحيح لاختبار API | 1 نقاط |
| شرح التعديلات اللازمة لإضافة سعر تذكرة الطفل | 1 نقاط |
معالجة الأخطاء في API باستخدام middleware مخصصة (3 points)
في تطبيقك السياحي، تريد معالجة الأخطاء التي قد تحدث أثناء معالجة الطلبات. على سبيل المثال، إذا طلب مستخدم مسار غير موجود، يجب إرجاع استجابة بتنسيق JSON تحتوي على رسالة خطأ وكود الحالة 404. استخدم middleware مخصصة لمعالجة هذه الأخطاء.
- يجب إرجاع استجابة JSON عند حدوث خطأ 404
- يجب أن تحتوي الاستجابة على: { "error": "Page not found", "status": 404 }
- اكتب الكودMiddleware لمعالجة الأخطاء من النوع 404.
- كيف تضيف هذا Middleware إلى تطبيق Express.js؟
- ماذا يحدث إذا طلبت مسار /invalid-path؟ اذكر الكود والرسالة التي ستظهر.
الحل الكامل
السؤال 1 (1 نقاط) — اكتب الكودMiddleware لمعالجة الأخطاء من النوع 404.
- إنشاء Middleware للأخطاء 404 — اكتب الدالة middleware التالية: app.use((req, res, next) => { res.status(404).json({ error: "Page not found", status: 404 }); });
← الكود: app.use((req, res, next) => { res.status(404).json({ error: "Page not found", status: 404 }); });
السؤال 2 (1 نقاط) — كيف تضيف هذا Middleware إلى تطبيق Express.js؟
- إضافة Middleware للتطبيق — ضع الكود بعد جميع تعريفات المسارات وقبل app.listen().
← ضع الكود بعد جميع تعريفات المسارات: app.get('/valid', (req, res) => { ... }); app.use((req, res, next) => { ... }); app.listen(3000, ...);
السؤال 3 (1 نقاط) — ماذا يحدث إذا طلبت مسار /invalid-path؟ اذكر الكود والرسالة التي ستظهر.
- اختبار المسار غير الموجود — افتح المتصفح واكتب الرابط http://localhost:3000/invalid-path ثم اضغط على Enter. يجب أن تظهر الاستجابة: { "error": "Page not found", "status": 404 }
← عند طلب /invalid-path، ستظهر الاستجابة: { "error": "Page not found", "status": 404 }
سلم التقدير
| الكودMiddleware لمعالجة الأخطاء 404 صحيح | 1 نقاط |
| إضافة Middleware للتطبيق في المكان الصحيح | 1 نقاط |
| الاستجابة الصحيحة عند طلب مسار غير موجود | 1 نقاط |
دمج Express.js مع قاعدة بيانات MongoDB لعرض معلومات الفنادق (5 points)
أنت مطور في شركة سياحية مصرية، وطلب منك إنشاء API يعرض معلومات عن الفنادق في القاهرة والإسكندرية. يجب استخدام MongoDB لتخزين البيانات واسترجاعها. استخدم مكتبة Mongoose لتسهيل التفاعل مع قاعدة البيانات. البيانات الافتراضية: فندق هيلتون القاهرة (5 نجوم، سعر الليلة 3000 جنيه)، فندق فور سيزونز الإسكندرية (5 نجوم، سعر الليلة 2500 جنيه).
- اسم قاعدة البيانات: egyp
- اسم المجموعة (collection): hotels
- البيانات: فندق هيلتون القاهرة (5 نجوم، 3000 جنيه/ليلة)، فندق فور سيزونز الإسكندرية (5 نجوم، 2500 جنيه/ليلة)
- اكتب الكود لتهيئة اتصال بقاعدة البيانات MongoDB باستخدام Mongoose.
- اكتب الكود لتعريف نموذج (Schema) للفنادق.
- اكتب الكود لإنشاء API يعرض جميع الفنادق.
- كيف تختبر أن API يعمل بشكل صحيح؟ اذكر الرابط الذي ستستخدمه.
الحل الكامل
السؤال 1 (1 نقاط) — اكتب الكود لتهيئة اتصال بقاعدة البيانات MongoDB باستخدام Mongoose.
- استيراد التبعيات — استخدم const mongoose = require('mongoose'); لاستيراد Mongoose.
- تهيئة الاتصال — استخدم const uri = 'mongodb://localhost:27017/egyp'; ثم قم بتهيئة الاتصال باستخدام mongoose.connect(uri).
← الكود: const mongoose = require('mongoose'); const uri = 'mongodb://localhost:27017/egyp'; mongoose.connect(uri) .then(() => console.log('متصل بقاعدة البيانات بنجاح')) .catch(err => console.error('خطأ في الاتصال:', err));
السؤال 2 (1 نقاط) — اكتب الكود لتعريف نموذج (Schema) للفنادق.
- تعريف النموذج (Schema) — استخدم const hotelSchema = new mongoose.Schema({ name: String, stars: Number, pricePerNight: Number, city: String }); ثم قم بإنشاء نموذج باستخدام const Hotel = mongoose.model('Hotel', hotelSchema);
← الكود: const hotelSchema = new mongoose.Schema({ name: String, stars: Number, pricePerNight: Number, city: String }); const Hotel = mongoose.model('Hotel', hotelSchema);
السؤال 3 (2 نقاط) — اكتب الكود لإنشاء API يعرض جميع الفنادق.
- إنشاء API لاسترجاع الفنادق — استخدم app.get('/hotels', async (req, res) => { const hotels = await Hotel.find(); res.json(hotels); }); لاسترجاع جميع الفنادق من قاعدة البيانات.
← الكود: app.get('/hotels', async (req, res) => { try { const hotels = await Hotel.find(); res.json(hotels); } catch (err) { res.status(500).json({ error: 'خطأ في استرجاع البيانات' }); } });
السؤال 4 (1 نقاط) — كيف تختبر أن API يعمل بشكل صحيح؟ اذكر الرابط الذي ستستخدمه.
- اختبار API — افتح المتصفح واكتب الرابط http://localhost:3000/hotels ثم اضغط على Enter. يجب أن تظهر البيانات بتنسيق JSON تحتوي على معلومات الفنادق.
سلم التقدير
| الكود لتهيئة اتصال بقاعدة البيانات MongoDB صحيح | 1 نقاط |
| الكود لتعريف نموذج الفندق (Schema) صحيح | 1 نقاط |
| الكود لإنشاء API لاسترجاع الفنادق يعمل بشكل صحيح | 2 نقاط |
| الرابط الصحيح لاختبار API | 1 نقاط |
إنشاء نظام تسجيل دخول بسيط باستخدام JWT (4 points)
أنت مطور في منصة تعليمية مصرية، وطلب منك إنشاء نظام تسجيل دخول بسيط لتطبيقك التعليمي. يجب استخدام JWT (JSON Web Token) للتحقق من هوية المستخدم. عند تسجيل الدخول بنجاح، يتم إرجاع token يمكن استخدامه في طلبات لاحقة. استخدم مكتبة jsonwebtoken.
- المستخدم الافتراضي: admin / password123
- السر (secret) للتشفير: 'mySecretKey'
- المنفذ: 3000
- اكتب الكود لإنشاء مسار POST /login للتحقق من بيانات الاعتماد وإرجاع token إذا كانت صحيحة.
- اكتب الكودMiddleware للتحقق من صلاحية token في المسارات المحمية.
- كيف تختبر تسجيل الدخول؟ اذكر الرابط والأمر الذي ستستخدمه في الطرفية.
الحل الكامل
السؤال 1 (2 نقاط) — اكتب الكود لإنشاء مسار POST /login للتحقق من بيانات الاعتماد وإرجاع token إذا كانت صحيحة.
- استيراد التبعيات — استخدم const jwt = require('jsonwebtoken'); لاستيراد مكتبة JWT.
- إنشاء مسار POST /login — تحقق من بيانات الاعتماد (admin/password123). إذا كانت صحيحة، قم بإنشاء token باستخدام jwt.sign() وإرجاعه.
← الكود: const jwt = require('jsonwebtoken'); app.post('/login', (req, res) => { const { username, password } = req.body; if (username === 'admin' && password === 'password123') { const token = jwt.sign({ username: 'admin' }, 'mySecretKey', { expiresIn: '1h' }); res.json({ token }); } else { res.status(401).json({ error: 'بيانات الاعتماد غير صحيحة' }); } });
السؤال 2 (1 نقاط) — اكتب الكودMiddleware للتحقق من صلاحية token في المسارات المحمية.
- إنشاء Middleware للتحقق من Token — اكتب الدالة middleware التالية: const authenticateToken = (req, res, next) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) return res.sendStatus(401); jwt.verify(token, 'mySecretKey', (err, user) => { if (err) return res.sendStatus(403); req.user = user; next(); }); };
← الكود: const authenticateToken = (req, res, next) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) return res.sendStatus(401); jwt.verify(token, 'mySecretKey', (err, user) => { if (err) return res.sendStatus(403); req.user = user; next(); }); };
السؤال 3 (1 نقاط) — كيف تختبر تسجيل الدخول؟ اذكر الرابط والأمر الذي ستستخدمه في الطرفية.
- اختبار تسجيل الدخول — استخدم أداة مثل Postman أو cURL لإرسال طلب POST إلى http://localhost:3000/login مع body: { "username": "admin", "password": "password123" }. ستحصل على token في الاستجابة.
← الأمر في الطرفية: curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d '{"username":"admin","password":"password123"}'
سلم التقدير
| الكود لمسار /login يعمل ويعيد token صحيح عند تسجيل الدخول بنجاح | 2 نقاط |
| الكودMiddleware للتحقق من token يعمل بشكل صحيح | 1 نقاط |
| طريقة الاختبار الصحيحة باستخدام cURL أو Postman | 1 نقاط |
نشر تطبيق Express.js على منصةRender (4 points)
أنت مطور في شركة مصرية، وطلب منك نشر تطبيق Express.js الخاص بك على منصةRender المجانية. يجب أن يكون التطبيق متاحا عبر الإنترنت. يجب عليك أولا رفع الكود إلى GitHub ثم نشره على Render. التطبيق يعرض رسالة ترحيبية بسيطة.
- عنوان مستودع GitHub: https://github.com/yourusername/my-express-app
- عنوان التطبيق المنشور: https://my-express-app.onrender.com
- اكتب الأوامر اللازمة لتهيئة مستودع GitHub لمشروعك.
- اكتب الأوامر اللازمة لنشر التطبيق على منصةRender.
- ماذا يجب أن تفعل إذا ظهر خطأ عند النشر؟ اذكر الخطوات الأساسية للتشخيص.
الحل الكامل
السؤال 1 (1 نقاط) — اكتب الأوامر اللازمة لتهيئة مستودع GitHub لمشروعك.
- تهيئة Git — في مجلد مشروعك، قم بتهيئة مستودع Git المحلي باستخدام git init.
- إضافة الملفات — قم بإضافة جميع الملفات باستخدام git add . ثم قم بعمل commit باستخدام git commit -m 'Initial commit'.
- ربط المستودع البعيد — قم بربط المستودع البعيد باستخدام git remote add origin https://github.com/yourusername/my-express-app.git ثم ادفع الكود باستخدام git push -u origin main.
← الأوامر: git init git add . git commit -m 'Initial commit' git remote add origin https://github.com/yourusername/my-express-app.git git push -u origin main
السؤال 2 (2 نقاط) — اكتب الأوامر اللازمة لنشر التطبيق على منصةRender.
- إنشاء تطبيق على Render — قم بتسجيل الدخول إلى حسابك على Render ثم انقر على 'New' ثم 'Web Service'. اختر مستودع GitHub الخاص بك ثم قم بتكوين التطبيق (اختر Node.js كبيئة، وحدد أمر التشغيل: node app.js). بعد ذلك، انقر على 'Create Web Service'.
← الخطوات: 1. تسجيل الدخول إلى Render 2. النقر على 'New' ثم 'Web Service' 3. اختيار مستودع GitHub 4. تحديد بيئة Node.js 5. كتابة أمر التشغيل: node app.js 6. النقر على 'Create Web Service'
السؤال 3 (1 نقاط) — ماذا يجب أن تفعل إذا ظهر خطأ عند النشر؟ اذكر الخطوات الأساسية للتشخيص.
- تشخيص الأخطاء — تحقق من سجلات البناء (Build Logs) في Render. تأكد من أن جميع التبعيات مثبتة (قم بإضافة package.json إذا لم يكن موجودا). تحقق من أن الأمر node app.js صحيح وأن الخادم يستمع على المنفذ الصحيح (عادة 3000 أو 8080).
← الخطوات: 1. فتح سجلات البناء في Render 2. التأكد من تثبيت جميع التبعيات (npm install) 3. التأكد من وجود package.json 4. التحقق من أن الخادم يستمع على المنفذ الصحيح (app.listen(process.env.PORT || 3000))
سلم التقدير
| الأوامر لتهيئة مستودع GitHub صحيحة | 1 نقاط |
| الخطوات الصحيحة لنشر التطبيق على Render | 2 نقاط |
| خطوات التشخيص الأساسية للأخطاء | 1 نقاط |
تحسين أداء API باستخدام Caching (4 points)
في تطبيقك السياحي، تلاحظ أن API الخاص بك يستغرق وقتا طويلا في استرجاع البيانات من قاعدة البيانات، مما يؤثر على تجربة المستخدم. قررت استخدام تقنية Caching لتخزين الاستجابات الشائعة (مثل قائمة المتاحف) في الذاكرة (in-memory) لتقليل زمن الاستجابة. استخدم مكتبة node-cache.
- البيانات الشائعة: قائمة المتاحف (لا تتغير كثيرا)
- زمن التخزين المؤقت: 5 دقائق
- اكتب الكودMiddleware لتطبيق Caching على المسار /museums.
- كيف تختبر أن Caching يعمل؟ اذكر الخطوات.
- ما هي الفائدة من استخدام Caching في هذا السيناريو؟
الحل الكامل
السؤال 1 (2 نقاط) — اكتب الكودMiddleware لتطبيق Caching على المسار /museums.
- استيراد node-cache — استخدم const NodeCache = require('node-cache'); لاستيراد المكتبة.
- إنشاء Middleware للتخزين المؤقت — اكتب الدالة middleware التالية: const cacheMiddleware = (req, res, next) => { if (req.method !== 'GET') return next(); const key = req.originalUrl; const cachedResponse = cache.get(key); if (cachedResponse) { return res.json(cachedResponse); } res.sendResponse = res.json; res.json = (data) => { cache.set(key, data); res.sendResponse(data); }; next(); };
← الكود: const NodeCache = require('node-cache'); const cache = new NodeCache({ stdTTL: 300 }); const cacheMiddleware = (req, res, next) => { if (req.method !== 'GET') return next(); const key = req.originalUrl; const cachedResponse = cache.get(key); if (cachedResponse) { return res.json(cachedResponse); } res.sendResponse = res.json; res.json = (data) => { cache.set(key, data); res.sendResponse(data); }; next(); };
السؤال 2 (1 نقاط) — كيف تختبر أن Caching يعمل؟ اذكر الخطوات.
- اختبار Caching — قم بفتح المتصفح واكتب الرابط http://localhost:3000/museums مرتين متتاليتين. في المرة الأولى، يجب أن يستغرق الاستعلام بعض الوقت (لأنه لم يتم تخزينه بعد). في المرة الثانية، يجب أن يظهر الاستجابة فورا (لأنها مستردة من التخزين المؤقت).
← الخطوات: 1. افتح المتصفح واكتب http://localhost:3000/museums (المرة الأولى) 2. أعد تحميل الصفحة (المرة الثانية) 3. لاحظ الفرق في زمن الاستجابة
السؤال 3 (1 نقاط) — ما هي الفائدة من استخدام Caching في هذا السيناريو؟
- الفائدة من Caching — يقلل زمن الاستجابة بشكل كبير، مما يحسن تجربة المستخدم ويقلل الحمل على قاعدة البيانات وخادم الويب.
← الفائدة: تقليل زمن الاستجابة بشكل كبير وتحسين تجربة المستخدم
سلم التقدير
| الكودMiddleware للتخزين المؤقت يعمل بشكل صحيح | 2 نقاط |
| الخطوات الصحيحة لاختبار Caching | 1 نقاط |
| شرح الفائدة من استخدام Caching بشكل صحيح | 1 نقاط |
تطبيق أفضل ممارسات الأمان في Express.js (3 points)
أنت مطور في شركة مصرية، وطلب منك تطبيق أفضل ممارسات الأمان في تطبيق Express.js الخاص بك. يجب حماية تطبيقك من هجمات XSS وCSRF وCORS غير الآمن. استخدم مكتبات Helmet و cors.
- يجب حماية جميع المسارات
- يجب السماح فقط للم origins المصرية (مثل localhost و egypt-tourism.com)
- اكتب الكود لتطبيق Helmet على تطبيق Express.js.
- اكتب الكود لتطبيق CORS مع السماح فقط لـ localhost و egypt-tourism.com.
- ما هي الهجمات التي يمنعها Helmet؟ اذكر ثلاثة منها.
الحل الكامل
السؤال 1 (1 نقاط) — اكتب الكود لتطبيق Helmet على تطبيق Express.js.
- استيراد Helmet — استخدم const helmet = require('helmet'); لاستيراد المكتبة.
- تطبيق Helmet — استخدم app.use(helmet()); لتطبيق جميع ممارسات Helmet الأمنية.
← الكود: const helmet = require('helmet'); app.use(helmet());
السؤال 2 (1 نقاط) — اكتب الكود لتطبيق CORS مع السماح فقط لـ localhost و egypt-tourism.com.
- استيراد CORS — استخدم const cors = require('cors'); لاستيراد المكتبة.
- تطبيق CORS — استخدم app.use(cors({ origin: ['http://localhost:3000', 'https://egypt-tourism.com'] })); للسماح فقط لـ localhost و egypt-tourism.com.
← الكود: const cors = require('cors'); app.use(cors({ origin: ['http://localhost:3000', 'https://egypt-tourism.com'] }));
السؤال 3 (1 نقاط) — ما هي الهجمات التي يمنعها Helmet؟ اذكر ثلاثة منها.
- الهجمات التي يمنعها Helmet — Helmet يمنع عدة هجمات شهيرة مثل XSS وClickjacking وMIME-sniffing.
← ثلاث هجمات: XSS (Cross-Site Scripting)، Clickjacking، و MIME-sniffing
سلم التقدير
| الكود لتطبيق Helmet صحيح | 1 نقاط |
| الكود لتطبيق CORS مع السماح فقط للأصول المحددة صحيح | 1 نقاط |
| ذكر ثلاثة هجمات يمنعها Helmet بشكل صحيح | 1 نقاط |