إعداد بيئة تطوير Hapi.js باستخدام ServBay
يُعد Hapi.js إطار عمل قوي ومرن مبني على Node.js، ومثالي لبناء التطبيقات وواجهات برمجة التطبيقات (API). يوفر ServBay للمطورين على Node.js بيئة تطوير محلية متكاملة، مع دعم للعديد من قواعد البيانات وإمكانيات خادم ويب سهلة التكوين. سيرشدك هذا الدليل إلى كيفية إنشاء وتشغيل مشروع Hapi.js في بيئة ServBay، وكيفية إعداد خاصية المواقع في ServBay للوصول إلى مشروعك، بالإضافة إلى توضيح كيفية الاتصال بقواعد البيانات المدمجة ضمن ServBay.
ما هو Hapi.js؟
Hapi.js هو إطار عمل أنشأته Walmart Labs لبناء التطبيقات والخدمات باستخدام Node.js. اشتهر بقوة نظام الإضافات الخاص به، والطريقة القائمة على التكوين، وخصائصه الأمنية المدمجة، مما يمَكِّنك كمطور من بناء تطبيقات ويب وواجهات برمجة تطبيقات عالية الأداء وسهلة الصيانة بكفاءة أكبر.
أهم مزايا وخصائص Hapi.js
- نظام الإضافات: يسمح نظام الإضافات القوي والمرن في Hapi.js بتوسيع وظائف الإطار بسهولة أو تنظيم منطق التطبيق إلى وحدات قابلة لإعادة الاستخدام.
- مبني على التكوين: يعتمد Hapi.js على أسلوب تطوير قائم على إعداد التكوينات التفصيلية لتحديد السلوكيات مثل التوجيه، والتحقق من المدخلات، والتخزين المؤقت، وغير ذلك.
- التحقق من المدخلات: يأتي Hapi.js مدعومًا بمكتبة Joi القوية، التي تتيح التحقق التصريحي من البيانات وتضمن صحتها وأمانها.
- منظومة بيئية غنية: مجتمع نشط ومجموعة واسعة من الإضافات الرسمية وغير الرسمية لتلبية متطلبات مثل المصادقة والتخزين المؤقت وتسجيل الأحداث (logging) وغيرها.
- الأمان: مزود بخيارات أمان مدمجة تساعدك على حماية تطبيقك من التهديدات الشائعة كفحص المدخلات والتحكم بـ CORS.
- السجلات وأدوات التصحيح: يوفر تسجيلًا شاملاً لدورة حياة الطلبات وأدوات تصحيح أخطاء متقدمة.
يسمح لك Hapi.js بالتركيز على منطق أعمال التطبيق، بينما يتكفل الإطار بمعالجة الجوانب التقنية المعقدة مثل إدارة الطلبات، والتوجيه، والتحقق، والأمان.
إعداد مشروع Hapi.js باستخدام ServBay
ستوضح هذه الخطوات كيفية إنشاء وتشغيل مشروع Hapi.js أساسي في بيئة Node.js المدمجة مع ServBay وكيفية ربطه بخاصية المواقع (البروكسي العكسي) في ServBay.
المتطلبات الأساسية
قبل البدء، تأكد من الآتي:
- تم تثبيت ServBay بنجاح على macOS.
- قمت بتفعيل حزمة Node.js من داخل تطبيق ServBay، وهو ما يمكنك فعله من تبويب "الحزم" في لوحة تحكم ServBay.
- لديك معرفة أساسية باستخدام الطرفية (Terminal) ومُدير npm لحزم Node.js.
إنشاء مشروع Hapi.js
تهيئة مجلد المشروع
افتح الطرفية وانتقل إلى مجلد المواقع الرئيسي الذي يقترحه ServBay
/Applications/ServBay/www
. ثم أنشئ مجلدًا جديدًا لمشروعك (مثالservbay-hapi-app
) وانتقل إليه:bashcd /Applications/ServBay/www mkdir servbay-hapi-app cd servbay-hapi-app
1
2
3تهيئة مشروع Node.js
في داخل مجلد المشروع، استخدم npm لتهيئة مشروع جديد:
bashnpm init -y
1سيؤدي ذلك لإنشاء ملف
package.json
.تثبيت اعتماديات Hapi.js
ثبّت مكتبة Hapi.js الأساسية:
bashnpm install @hapi/hapi
1سيتم إضافة
@hapi/hapi
ضمن اعتماديات مشروعك.إنشاء الملف الرئيسي للتطبيق
أنشئ ملفًا باسم
server.js
في جذر المشروع وأضف الكود التالي لإنشاء خادم Hapi.js بسيط:javascript'use strict'; // تفعيل الوضع الصارم const Hapi = require('@hapi/hapi'); const init = async () => { const server = Hapi.server({ port: process.env.PORT || 3000, // افتراضيًا على المنفذ 3000 أو يتم تحديده من خلال متغير PORT host: 'localhost' // الاستماع على عنوان loopback المحلي }); // تعريف مسار root بسيط server.route({ method: 'GET', path: '/', handler: (request, h) => { return 'Hello from Hapi.js powered by ServBay!'; } }); // بدء تشغيل الخادم await server.start(); console.log('Server running on %s', server.info.uri); }; // التعامل مع الأخطاء غير المعالجة في Promise process.on('unhandledRejection', (err) => { console.error(err); process.exit(1); // إنهاء العملية }); // استدعاء دالة init لتشغيل التطبيق init();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33ينشئ هذا الكود خادم Hapi يستمع على
localhost
في المنفذ المحدد (افتراضيًا 3000)، ويعرّف معالجًا بسيطًا لمسار الجذر/
.
الدخول في وضع التطوير وتكوين موقع عبر ServBay
أثناء التطوير يمكنك تشغيل تطبيق Node.js محليًا، وربطه باسم نطاق مخصص بواسطة بروكسي عكسي في ServBay، والاستفادة من شهادة SSL المقدمة.
تشغيل خادم Hapi.js في وضع التطوير
في الطرفية، تأكد أنك ضمن مجلد المشروع
servbay-hapi-app
ثم شغّل الخادم مع تحديد منفذ مناسب متوافق مع البروكسي العكسي لـ ServBay (مثال: 8585):bashPORT=8585 node server.js
1سيبدأ الخادم وتظهر لك رسالة بعنوان URI كـ
Server running on http://localhost:8585
. اترك نافذة الطرفية نشطة أثناء العمل.تكوين موقع جديد (بروكسي عكسي) في ServBay
من تطبيق ServBay، انتقل إلى تبويب "المواقع"، ثم اضغط على زر "+" أسفل اليسار لإضافة موقع جديد.
- الاسم (Name):
ServBay Hapi Dev
(يمكنك تغييره حسب رغبتك) - النطاق (Domain):
servbay-hapi-dev.servbay.demo
(يفضل استخدام امتداد.servbay.demo
لتجنب تعارض مع نطاقات الإنترنت والاستفادة من شهادة CA المحلية لدى ServBay) - نوع الموقع (Type): اختر
بروكسي عكسي (Reverse Proxy)
- البروكسي إلى (Proxy to):
- البروتوكول (Protocol):
http
- عنوان IP:
127.0.0.1
- المنفذ (Port):
8585
(يجب أن يتطابق مع المنفذ في الأمر السابق)
- البروتوكول (Protocol):
اضغط "إضافة" لإكمال الإعداد. سيقوم ServBay تلقائيًا بتهيئة خادم ويب مناسب (Caddy أو Nginx) لتوجيه أي طلب إلى
https://servbay-hapi-dev.servbay.demo
نحوhttp://127.0.0.1:8585
. كما يقوم بمضاعفة أمان الموقع بإصدار شهادة SSL محلية وموثوقة تلقائيًا عبر CA الخاصة بـ ServBay.لمزيد من التفاصيل حول إعداد المواقع في ServBay، راجع دليل إعداد المواقع في ServBay.
- الاسم (Name):
الوصول إلى تطبيق Hapi.js قيد التطوير
افتح متصفح الإنترنت وادخل إلى النطاق الذي قمت بإعداده:
https://servbay-hapi-dev.servbay.demo
. ينبغي أن تظهر لك رسالة "Hello from Hapi.js powered by ServBay!".يمكنك الآن تعديل ملف
server.js
، وسينعكس التحديث في المتصفح مباشرة – خاصة إذا استخدمت أدوات لإعادة التحميل الحي مثل nodemon.
نشر إصدار الإنتاج (مثال)
في بيئة الإنتاج ستحتاج إلى إدارة العمليات بشكل أقوى (باستخدام أدوات مثل PM2) وضبط إعدادات مختلفة. إليك مثالًا بسيطًا لتشغيل التطبيق على منفذ مختلف واستخدام ServBay كبروكسي عكسي:
تشغيل خادم Hapi.js للإنتاج
لتشغيل التطبيق بإعدادات إنتاجية ومنفذ مخصص (مثال: 8586):
bashPORT=8586 NODE_ENV=production node server.js
1(ملاحظة: في الإنتاج الحقيقي يفضل استخدام PM2 أو ما شابه لإدارة العمليات تلقائيًا واستمراريتها. يدعم ServBay التكامل مع PM2.)
إعداد موقع جديد (بروكسي عكسي) في ServBay للإنتاج
من تبويب "المواقع" في تطبيق ServBay، اضغط "+" وقم بملء البيانات التالية:
- الاسم (Name):
ServBay Hapi Prod
- النطاق (Domain):
servbay-hapi-prod.servbay.demo
- نوع الموقع (Type):
بروكسي عكسي (Reverse Proxy)
- البروكسي إلى (Proxy to):
- البروتوكول:
http
- عنوان IP:
127.0.0.1
- المنفذ (Port):
8586
- البروتوكول:
ثم اضغط "إضافة".
- الاسم (Name):
الوصول إلى نسخة الإنتاج
افتح متصفحك إلى
https://servbay-hapi-prod.servbay.demo
. سترى نفس نتيجة التطوير (إلا إذا كان هناك فروقات في السلوك حسب متغير NODE_ENV).
عن طريق خاصية المواقع في ServBay يمكنك إدارة عدة نطاقات تطوير أو محاكاة بيئة إنتاج، وربط كل نطاق بمنفذ مختلف حيث يعمل كل تطبيق Hapi.js أو أي تطبيق Node.js آخر.
ربط تطبيقك بقاعدة بيانات عبر ServBay
يدعم ServBay العديد من قواعد البيانات مثل MySQL، MariaDB، PostgreSQL، MongoDB و Redis. يوضح هذا القسم كيفية ربط مشروع Hapi.js بأي منها.
ملاحظة هامة: قبل ربط تطبيقك بقاعدة بيانات، تحقق من أن الحزمة الخاصة بقاعدة البيانات التي تحتاجها مفعلة من تبويب "الحزم" في ServBay وأن الخدمة مشغلة. تحقق من الحالة من لوحة تحكم ServBay.
بيانات حسابات قواعد البيانات الافتراضية في ServBay:
- MySQL/MariaDB: اسم المستخدم
root
، كلمة السرpassword
- PostgreSQL: اسم المستخدم
user
، كلمة السرpassword
- MongoDB: بدون مصادقة (إفتراضيًا)
- Redis: بدون مصادقة (إفتراضيًا)
تنبيه: حفاظًا على الأمان، ننصح بشدة بتغيير كلمات السر الافتراضية خاصة عند الاستخدام خارج جهازك المحلي. يمكنك إعادة تعيين كلمة السر بسهولة من خلال ServBay. لمزيد من التفاصيل راجع دليل إعادة تعيين كلمة مرور قاعدة البيانات.
أدناه تجد أمثلة أكواد للاتصال بمختلف قواعد البيانات (تأكد أولًا من تثبيت حزمة العميل المناسبة عبر npm).
الاتصال بـ MySQL
تثبيت حزمة عميل MySQL:
bashnpm install mysql2 # أو mysql
1مثال كود الاتصال (مع استخدام
mysql2
):javascriptconst mysql = require('mysql2'); const connection = mysql.createConnection({ host: 'localhost', user: 'root', // اسم المستخدم الافتراضي لـ ServBay password: 'password', // كلمة المرور الافتراضية لـ ServBay database: 'servbay_hapi_app' // غيّر اسم قاعدة البيانات حسب الحاجة }); connection.connect(err => { if (err) { console.error('Error connecting to MySQL: ' + err.stack); return; } console.log('Connected to MySQL as id ' + connection.threadId); }); // أغلق الاتصال عند الانتهاء // connection.end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19الاتصال بـ MariaDB
تثبيت حزمة العميل:
bashnpm install mariadb
1مثال للاتصال:
javascriptconst mariadb = require('mariadb'); const pool = mariadb.createPool({ host: 'localhost', user: 'root', // اسم المستخدم الافتراضي لـ ServBay password: 'password', // كلمة المرور الافتراضية لـ ServBay database: 'servbay_hapi_app', // غيّر حسب قاعدة بياناتك connectionLimit: 5 // حجم تجمع الاتصالات }); pool.getConnection() .then(conn => { console.log("Connected to MariaDB"); // استخدم conn.query(...) للتنفيذ conn.release(); // إعادة الاتصال إلى التجمع }) .catch(err => { console.error("Not connected to MariaDB due to error: " + err); });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18الاتصال بـ PostgreSQL
تثبيت الحزمة:
bashnpm install pg
1مثال للاتصال:
javascriptconst { Pool } = require('pg'); const pool = new Pool({ user: 'user', // اسم المستخدم الافتراضي لـ ServBay host: 'localhost', database: 'servbay_hapi_app', // غيّر حسب قاعدة بياناتك password: 'password', // كلمة المرور الافتراضية لـ ServBay port: 5432, // المنفذ الافتراضي لـ PostgreSQL }); pool.connect((err, client, done) => { if (err) { console.error('Error connecting to PostgreSQL: ', err); return; } console.log('Connected to PostgreSQL'); client.query('SELECT NOW()', (err, res) => { done(); // تحرير الاتصال if (err) { console.error('Error executing query', err.stack); } else { console.log('PostgreSQL current time:', res.rows[0].now); } }); }); // سيتم إغلاق تجمع الاتصالات تلقائيًا عند الخروج من التطبيق // pool.end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27الاتصال بـ MongoDB
تثبيت الحزمة:
bashnpm install mongoose # أو mongodb
1مثال باستخدام
mongoose
:javascriptconst mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/servbay-hapi-app', { useNewUrlParser: true, useUnifiedTopology: true, // MongoDB المدمج مع ServBay لايتطلب مصادقة إفتراضيًا، إذا فُعّلت أضف authSource, user, pass // authSource: 'admin', // user: 'your_username', // pass: 'your_password', }) .then(() => console.log('MongoDB connected')) .catch(err => console.error('MongoDB connection error:', err)); // اتصال Mongoose يظل نشطًا طوال فترة تشغيل التطبيق // لإنهائه: mongoose.connection.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15الاتصال بـ Redis
تثبيت الحزمة:
bashnpm install redis
1مثال للاتصال:
javascriptconst redis = require('redis'); // الاتصال بالمعطيات الافتراضية: host: 'localhost', port: 6379 const client = redis.createClient(); client.on('error', function (err) { console.error('Redis Error: ' + err); }); client.on('connect', function () { console.log('Redis client connected'); }); // الاتصال بخادم Redis client.connect(); // بالنسبة لـ redis v4+ يجب استخدام connect() // مثال لتعيين وقراءة القيم // async function exampleRedisUsage() { // await client.set('mykey', 'myvalue'); // const value = await client.get('mykey'); // console.log('Value from Redis:', value); // await client.del('mykey'); // } // exampleRedisUsage(); // أغلق الاتصال عند انتهاء التطبيق // client.quit();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
بدمج أمثلة الاتصال هذه في مشروع Hapi.js الخاص بك، ستحصل على بيئة تطوير محلية متكاملة مع قواعد بيانات متعددة مقدمة ضمن ServBay.
الخلاصة
يتيح لك ServBay بناء بيئة تطوير Hapi.js كاملة بفاعلية على نظام macOS. فهو يوفر كل ما تحتاجه من تثبيت وإدارة Node.js، وقواعد البيانات الجاهزة، بالإضافة إلى تسهيلات الوصول للموقع عبر ميزة المواقع (بروكسي عكسي وإعداد SSL تلقائي). باتباعك لهذا الدليل يمكنك الشروع بسرعة في تطوير تطبيقك بـ Hapi.js والاستفادة من قدرات ServBay في تسريع دورة التطوير لديك.