استكشف أنماط البرمجيات الوسيطة المتقدمة في Express.js لبناء تطبيقات ويب قوية وقابلة للتطوير وقابلة للصيانة لجمهور عالمي. تعلم عن معالجة الأخطاء والمصادقة والحد من المعدل والمزيد.
Express.js Middleware: إتقان الأنماط المتقدمة للتطبيقات القابلة للتطوير
Express.js، وهو إطار عمل ويب سريع وغير متحيز وبسيط لـ Node.js، هو حجر الزاوية لبناء تطبيقات الويب وواجهات برمجة التطبيقات. في جوهره يكمن المفهوم القوي للبرمجيات الوسيطة. يتعمق منشور المدونة هذا في أنماط البرمجيات الوسيطة المتقدمة، مما يوفر لك المعرفة والأمثلة العملية لإنشاء تطبيقات قوية وقابلة للتطوير وقابلة للصيانة ومناسبة لجمهور عالمي. سنستكشف تقنيات معالجة الأخطاء والمصادقة والتفويض وتحديد المعدل والجوانب الهامة الأخرى لبناء تطبيقات الويب الحديثة.
فهم البرمجيات الوسيطة: الأساس
وظائف البرمجيات الوسيطة في Express.js هي وظائف يمكنها الوصول إلى كائن الطلب (req
) وكائن الاستجابة (res
) ووظيفة البرمجيات الوسيطة التالية في دورة طلب-استجابة التطبيق. يمكن لوظائف البرمجيات الوسيطة أداء مجموعة متنوعة من المهام، بما في ذلك:
- تنفيذ أي كود.
- إجراء تغييرات على كائنات الطلب والاستجابة.
- إنهاء دورة الطلب-الاستجابة.
- استدعاء وظيفة البرمجيات الوسيطة التالية في المكدس.
البرمجيات الوسيطة هي في الأساس خط أنابيب. تؤدي كل قطعة من البرمجيات الوسيطة وظيفتها المحددة، ثم، اختياريًا، تنقل التحكم إلى البرمجيات الوسيطة التالية في السلسلة. يشجع هذا النهج المعياري على إعادة استخدام التعليمات البرمجية وفصل المخاوف وهندسة التطبيقات الأنظف.
تشريح البرمجيات الوسيطة
تتبع دالة البرمجيات الوسيطة النموذجية هذا الهيكل:
function myMiddleware(req, res, next) {
// Perform actions
// Example: Log request information
console.log(`Request: ${req.method} ${req.url}`);
// Call the next middleware in the stack
next();
}
الوظيفة next()
حاسمة. إنها تشير إلى Express.js بأن البرمجيات الوسيطة الحالية قد أنهت عملها ويجب تمرير التحكم إلى وظيفة البرمجيات الوسيطة التالية. إذا لم يتم استدعاء next()
، فسيتم إيقاف الطلب مؤقتًا، ولن يتم إرسال الاستجابة أبدًا.
أنواع البرمجيات الوسيطة
يوفر Express.js عدة أنواع من البرمجيات الوسيطة، كل منها يخدم غرضًا مميزًا:
- البرمجيات الوسيطة على مستوى التطبيق: يتم تطبيقها على جميع المسارات أو مسارات معينة.
- البرمجيات الوسيطة على مستوى الموجه: يتم تطبيقها على المسارات المحددة داخل مثيل الموجه.
- البرمجيات الوسيطة لمعالجة الأخطاء: مصممة خصيصًا للتعامل مع الأخطاء. يتم وضعها *بعد* تعريفات المسار في مكدس البرمجيات الوسيطة.
- البرمجيات الوسيطة المضمنة: مضمنة بواسطة Express.js (على سبيل المثال،
express.static
لخدمة الملفات الثابتة). - البرمجيات الوسيطة التابعة لجهات خارجية: مثبتة من حزم npm (على سبيل المثال، body-parser، cookie-parser).
أنماط البرمجيات الوسيطة المتقدمة
دعنا نستكشف بعض الأنماط المتقدمة التي يمكن أن تحسن بشكل كبير وظائف تطبيق Express.js وأمانه وقابليته للصيانة.
1. البرمجيات الوسيطة لمعالجة الأخطاء
تعتبر معالجة الأخطاء الفعالة ذات أهمية قصوى لبناء تطبيقات موثوقة. يوفر Express.js وظيفة برمجيات وسيطة مخصصة لمعالجة الأخطاء، والتي يتم وضعها *أخيرًا* في مكدس البرمجيات الوسيطة. تأخذ هذه الوظيفة أربع وسيطات: (err, req, res, next)
.
إليك مثال:
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack); // Log the error for debugging
res.status(500).send('Something broke!'); // Respond with an appropriate status code
});
اعتبارات رئيسية لمعالجة الأخطاء:
- تسجيل الأخطاء: استخدم مكتبة تسجيل (على سبيل المثال، Winston، Bunyan) لتسجيل الأخطاء لتصحيح الأخطاء والمراقبة. ضع في اعتبارك تسجيل مستويات مختلفة من الشدة (على سبيل المثال،
error
،warn
،info
،debug
) - رموز الحالة: قم بإرجاع رموز حالة HTTP المناسبة (على سبيل المثال، 400 لطلب سيئ، 401 غير مصرح به، 500 لخطأ الخادم الداخلي) للتواصل طبيعة الخطأ للعميل.
- رسائل الخطأ: قم بتوفير رسائل خطأ إعلامية وآمنة للعميل. تجنب الكشف عن معلومات حساسة في الاستجابة. ضع في اعتبارك استخدام رمز خطأ فريد لتتبع المشكلات داخليًا أثناء إرجاع رسالة عامة للمستخدم.
- معالجة الأخطاء المركزية: قم بتجميع معالجة الأخطاء في وظيفة برمجيات وسيطة مخصصة لتحسين التنظيم والصيانة. قم بإنشاء فئات أخطاء مخصصة لسيناريوهات أخطاء مختلفة.
2. برمجيات المصادقة والتفويض الوسيطة
يعد تأمين واجهة برمجة التطبيقات الخاصة بك وحماية البيانات الحساسة أمرًا بالغ الأهمية. تتحقق المصادقة من هوية المستخدم، بينما يحدد التفويض ما يُسمح للمستخدم بفعله.
استراتيجيات المصادقة:
- رموز الويب JSON (JWT): طريقة مصادقة شائعة بلا حالة، مناسبة لواجهات برمجة التطبيقات. يصدر الخادم JWT للعميل عند تسجيل الدخول بنجاح. ثم يقوم العميل بتضمين هذا الرمز المميز في الطلبات اللاحقة. تُستخدم مكتبات مثل
jsonwebtoken
بشكل شائع. - الجلسات: الاحتفاظ بجلسات المستخدمين باستخدام ملفات تعريف الارتباط. هذا مناسب لتطبيقات الويب ولكنه قد يكون أقل قابلية للتطوير من JWT. تسهل مكتبات مثل
express-session
إدارة الجلسة. - OAuth 2.0: معيار معتمد على نطاق واسع للتفويض المفوض، مما يسمح للمستخدمين بمنح الوصول إلى مواردهم دون مشاركة بيانات اعتمادهم مباشرةً. (على سبيل المثال، تسجيل الدخول باستخدام Google أو Facebook وما إلى ذلك). قم بتنفيذ تدفق OAuth باستخدام مكتبات مثل
passport.js
مع استراتيجيات OAuth محددة.
استراتيجيات التفويض:
- التحكم في الوصول المستند إلى الدور (RBAC): قم بتعيين أدوار (على سبيل المثال، المسؤول، المحرر، المستخدم) للمستخدمين ومنح الأذونات بناءً على هذه الأدوار.
- التحكم في الوصول المستند إلى السمة (ABAC): نهج أكثر مرونة يستخدم سمات المستخدم والمورد والبيئة لتحديد الوصول.
مثال (مصادقة JWT):
const jwt = require('jsonwebtoken');
const secretKey = 'YOUR_SECRET_KEY'; // Replace with a strong, environment variable-based key
// Middleware to verify JWT tokens
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return res.sendStatus(401); // Unauthorized
jwt.verify(token, secretKey, (err, user) => {
if (err) return res.sendStatus(403); // Forbidden
req.user = user; // Attach user data to the request
next();
});
}
// Example route protected by authentication
app.get('/profile', authenticateToken, (req, res) => {
res.json({ message: `Welcome, ${req.user.username}` });
});
اعتبارات أمنية هامة:
- التخزين الآمن لبيانات الاعتماد: لا تقم أبدًا بتخزين كلمات المرور بنص عادي. استخدم خوارزميات تجزئة كلمات المرور القوية مثل bcrypt أو Argon2.
- HTTPS: استخدم دائمًا HTTPS لتشفير الاتصال بين العميل والخادم.
- التحقق من صحة الإدخال: تحقق من صحة جميع مدخلات المستخدم لمنع الثغرات الأمنية مثل حقن SQL والبرمجة النصية عبر المواقع (XSS).
- عمليات التدقيق الأمني المنتظمة: قم بإجراء عمليات تدقيق أمني منتظمة لتحديد ومعالجة الثغرات الأمنية المحتملة.
- متغيرات البيئة: قم بتخزين المعلومات الحساسة (مفاتيح واجهة برمجة التطبيقات، بيانات اعتماد قاعدة البيانات، المفاتيح السرية) كمتغيرات بيئة بدلاً من ترميزها بشكل ثابت في التعليمات البرمجية الخاصة بك. هذا يجعل إدارة التكوين أسهل ويعزز أفضل ممارسات الأمان.
3. برمجيات تحديد معدل الحد الوسيطة
يؤدي تحديد المعدل إلى حماية واجهة برمجة التطبيقات الخاصة بك من سوء الاستخدام، مثل هجمات حجب الخدمة (DoS) والاستهلاك المفرط للموارد. يقيد عدد الطلبات التي يمكن للعميل تقديمها ضمن إطار زمني محدد.
تُستخدم مكتبات مثل express-rate-limit
بشكل شائع لتحديد المعدل. ضع في اعتبارك أيضًا الحزمة helmet
، والتي ستتضمن وظائف تحديد المعدل الأساسي بالإضافة إلى مجموعة من التحسينات الأمنية الأخرى.
مثال (باستخدام express-rate-limit):
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP, please try again after 15 minutes',
});
// Apply the rate limiter to specific routes
app.use('/api/', limiter);
// Alternatively, apply to all routes (generally less desirable unless all traffic should be treated equally)
// app.use(limiter);
تشمل خيارات التخصيص لتحديد المعدل ما يلي:
- تحديد المعدل المستند إلى عنوان IP: النهج الأكثر شيوعًا.
- تحديد المعدل المستند إلى المستخدم: يتطلب مصادقة المستخدم.
- تحديد المعدل المستند إلى طريقة الطلب: حدد طرق HTTP محددة (على سبيل المثال، طلبات POST).
- التخزين المخصص: قم بتخزين معلومات تحديد المعدل في قاعدة بيانات (على سبيل المثال، Redis، MongoDB) لتحسين قابلية التوسع عبر مثيلات خادم متعددة.
4. البرمجيات الوسيطة لتحليل نص الطلب
بشكل افتراضي، لا يقوم Express.js بتحليل نص الطلب. ستحتاج إلى استخدام البرمجيات الوسيطة للتعامل مع تنسيقات النص المختلفة، مثل JSON والبيانات المشفرة بعنوان URL. على الرغم من أن التطبيقات القديمة ربما استخدمت حزمًا مثل `body-parser`، إلا أن أفضل ممارسة حالية هي استخدام البرمجيات الوسيطة المضمنة في Express، كما هو متاح منذ Express v4.16.
مثال (باستخدام البرمجيات الوسيطة المضمنة):
app.use(express.json()); // Parses JSON-encoded request bodies
app.use(express.urlencoded({ extended: true })); // Parses URL-encoded request bodies
تقوم البرمجيات الوسيطة `express.json()` بتحليل الطلبات الواردة مع حمولات JSON وتجعل البيانات التي تم تحليلها متاحة في `req.body`. تقوم البرمجيات الوسيطة `express.urlencoded()` بتحليل الطلبات الواردة مع حمولات مشفرة بعنوان URL. يسمح الخيار `{ extended: true }` بتحليل الكائنات والمصفوفات الغنية.
5. البرمجيات الوسيطة للتسجيل
يعد التسجيل الفعال أمرًا ضروريًا لتصحيح الأخطاء والمراقبة وتدقيق تطبيقك. يمكن للبرمجيات الوسيطة اعتراض الطلبات والاستجابات لتسجيل المعلومات ذات الصلة.
مثال (البرمجيات الوسيطة البسيطة للتسجيل):
const morgan = require('morgan'); // A popular HTTP request logger
app.use(morgan('dev')); // Log requests in the 'dev' format
// Another example, custom formatting
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next();
});
بالنسبة لبيئات الإنتاج، ضع في اعتبارك استخدام مكتبة تسجيل أكثر قوة (على سبيل المثال، Winston، Bunyan) مع ما يلي:
- مستويات التسجيل: استخدم مستويات تسجيل مختلفة (على سبيل المثال،
debug
،info
،warn
،error
) لتصنيف رسائل السجل بناءً على شدتها. - تناوب السجل: قم بتنفيذ تناوب السجل لإدارة حجم ملف السجل ومنع مشكلات مساحة القرص.
- التسجيل المركزي: أرسل السجلات إلى خدمة تسجيل مركزية (على سبيل المثال، ELK stack (Elasticsearch، Logstash، Kibana)، Splunk) لتسهيل المراقبة والتحليل.
6. البرمجيات الوسيطة للتحقق من صحة الطلبات
تحقق من صحة الطلبات الواردة لضمان سلامة البيانات ومنع السلوك غير المتوقع. يمكن أن يشمل ذلك التحقق من صحة رؤوس الطلبات ومعلمات الاستعلام وبيانات نص الطلب.
مكتبات للتحقق من صحة الطلبات:
- Joi: مكتبة تحقق من الصحة قوية ومرنة لتحديد المخططات والتحقق من صحة البيانات.
- Ajv: مدقق مخطط JSON سريع.
- Express-validator: مجموعة من البرمجيات الوسيطة للتعبير والتي تغلف validator.js لسهولة الاستخدام مع Express.
مثال (باستخدام Joi):
const Joi = require('joi');
const userSchema = Joi.object({
username: Joi.string().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
});
function validateUser(req, res, next) {
const { error } = userSchema.validate(req.body, { abortEarly: false }); // Set abortEarly to false to get all errors
if (error) {
return res.status(400).json({ errors: error.details.map(err => err.message) }); // Return detailed error messages
}
next();
}
app.post('/users', validateUser, (req, res) => {
// User data is valid, proceed with user creation
res.status(201).json({ message: 'User created successfully' });
});
أفضل ممارسات التحقق من صحة الطلبات:
- التحقق من الصحة المستند إلى المخطط: حدد المخططات لتحديد البنية وأنواع البيانات المتوقعة لبياناتك.
- معالجة الأخطاء: قم بإرجاع رسائل خطأ إعلامية إلى العميل عند فشل التحقق من الصحة.
- تطهير الإدخال: قم بتطهير مدخلات المستخدم لمنع الثغرات الأمنية مثل البرمجة النصية عبر المواقع (XSS). بينما يركز التحقق من صحة الإدخال على *ما* هو مقبول، يركز التطهير على *كيفية* تمثيل الإدخال لإزالة العناصر الضارة.
- التحقق من الصحة المركزي: قم بإنشاء وظائف برمجيات وسيطة للتحقق من الصحة قابلة لإعادة الاستخدام لتجنب تكرار التعليمات البرمجية.
7. البرمجيات الوسيطة لضغط الاستجابة
قم بتحسين أداء تطبيقك عن طريق ضغط الاستجابات قبل إرسالها إلى العميل. يؤدي هذا إلى تقليل كمية البيانات المنقولة، مما يؤدي إلى أوقات تحميل أسرع.
مثال (باستخدام البرمجيات الوسيطة للضغط):
const compression = require('compression');
app.use(compression()); // Enable response compression (e.g., gzip)
تعمل البرمجيات الوسيطة compression
على ضغط الاستجابات تلقائيًا باستخدام gzip أو deflate، استنادًا إلى رأس Accept-Encoding
الخاص بالعميل. هذا مفيد بشكل خاص لتقديم الأصول الثابتة واستجابات JSON الكبيرة.
8. البرمجيات الوسيطة CORS (مشاركة الموارد عبر الأصل)
إذا كان تطبيق واجهة برمجة التطبيقات أو الويب الخاص بك يحتاج إلى قبول الطلبات من نطاقات مختلفة (أصول)، فستحتاج إلى تكوين CORS. يتضمن هذا تعيين رؤوس HTTP المناسبة للسماح بطلبات عبر الأصل.
مثال (باستخدام البرمجيات الوسيطة CORS):
const cors = require('cors');
const corsOptions = {
origin: 'https://your-allowed-domain.com',
methods: 'GET,POST,PUT,DELETE',
allowedHeaders: 'Content-Type,Authorization'
};
app.use(cors(corsOptions));
// OR to allow all origins (for development or internal APIs -- use with caution!)
// app.use(cors());
اعتبارات مهمة لـ CORS:
- Origin: حدد الأصول (النطاقات) المسموح بها لمنع الوصول غير المصرح به. من الآمن عمومًا وضع قائمة بيضاء بالأصول المحددة بدلاً من السماح بجميع الأصول (
*
). - Methods: حدد طرق HTTP المسموح بها (على سبيل المثال، GET، POST، PUT، DELETE).
- Headers: حدد رؤوس الطلبات المسموح بها.
- طلبات ما قبل الطيران: بالنسبة للطلبات المعقدة (على سبيل المثال، مع رؤوس مخصصة أو طرق أخرى غير GET، POST، HEAD)، سيرسل المتصفح طلبًا مسبقًا (OPTIONS) للتحقق مما إذا كان الطلب الفعلي مسموحًا به. يجب أن يستجيب الخادم برؤوس CORS المناسبة لنجاح طلب ما قبل الطيران.
9. خدمة الملفات الثابتة
يوفر Express.js برمجيات وسيطة مضمنة لخدمة الملفات الثابتة (على سبيل المثال، HTML، CSS، JavaScript، الصور). يُستخدم هذا عادةً لخدمة الواجهة الأمامية لتطبيقك.
مثال (باستخدام express.static):
app.use(express.static('public')); // Serve files from the 'public' directory
ضع أصولك الثابتة في الدليل public
(أو أي دليل آخر تحدده). سيقوم Express.js بعد ذلك تلقائيًا بتقديم هذه الملفات بناءً على مسارات ملفاتها.
10. البرمجيات الوسيطة المخصصة لمهام معينة
إلى جانب الأنماط التي تمت مناقشتها، يمكنك إنشاء برمجيات وسيطة مخصصة مصممة خصيصًا للاحتياجات المحددة لتطبيقك. يتيح لك ذلك تضمين منطق معقد وتعزيز إعادة استخدام التعليمات البرمجية.
مثال (البرمجيات الوسيطة المخصصة لعناصر التحكم في الميزات):
// Custom middleware to enable/disable features based on a configuration file
const featureFlags = require('./config/feature-flags.json');
function featureFlagMiddleware(featureName) {
return (req, res, next) => {
if (featureFlags[featureName] === true) {
next(); // Feature is enabled, continue
} else {
res.status(404).send('Feature not available'); // Feature is disabled
}
};
}
// Example usage
app.get('/new-feature', featureFlagMiddleware('newFeatureEnabled'), (req, res) => {
res.send('This is the new feature!');
});
يوضح هذا المثال كيفية استخدام البرمجيات الوسيطة المخصصة للتحكم في الوصول إلى مسارات معينة بناءً على عناصر التحكم في الميزات. يسمح هذا للمطورين بالتحكم في إصدار الميزات دون إعادة النشر أو تغيير التعليمات البرمجية التي لم يتم فحصها بالكامل، وهي ممارسة شائعة في تطوير البرامج.
أفضل الممارسات والاعتبارات للتطبيقات العالمية
- الأداء: قم بتحسين البرمجيات الوسيطة للأداء، خاصة في التطبيقات ذات حركة المرور العالية. قلل من استخدام العمليات المكثفة لوحدة المعالجة المركزية. ضع في اعتبارك استخدام استراتيجيات التخزين المؤقت.
- قابلية التوسع: صمم البرمجيات الوسيطة الخاصة بك لتوسيع نطاقها أفقيًا. تجنب تخزين بيانات الجلسة في الذاكرة؛ استخدم ذاكرة تخزين مؤقت موزعة مثل Redis أو Memcached.
- الأمان: قم بتنفيذ أفضل الممارسات الأمنية، بما في ذلك التحقق من صحة الإدخال والمصادقة والتفويض والحماية من نقاط الضعف الشائعة على الويب. هذا أمر بالغ الأهمية، خاصة بالنظر إلى الطبيعة الدولية لجمهورك.
- قابلية الصيانة: اكتب تعليمات برمجية نظيفة وموثقة جيدًا ومعيارية. استخدم اصطلاحات تسمية واضحة واتبع نمط ترميز متسقًا. قم بتوحيد البرمجيات الوسيطة الخاصة بك لتسهيل الصيانة والتحديثات.
- قابلية الاختبار: اكتب اختبارات الوحدة واختبارات التكامل للبرمجيات الوسيطة الخاصة بك للتأكد من أنها تعمل بشكل صحيح ولاكتشاف الأخطاء المحتملة في وقت مبكر. اختبر البرمجيات الوسيطة الخاصة بك في مجموعة متنوعة من البيئات.
- التدويل (i18n) والترجمة (l10n): ضع في اعتبارك التدويل والترجمة إذا كان تطبيقك يدعم لغات أو مناطق متعددة. قدم رسائل خطأ ومحتوى وتنسيقًا مترجمًا لتحسين تجربة المستخدم. يمكن لأطر العمل مثل i18next تسهيل جهود i18n.
- المناطق الزمنية والتعامل مع التاريخ/الوقت: كن على دراية بالمناطق الزمنية وتعامل مع بيانات التاريخ/الوقت بعناية، خاصة عند العمل مع جمهور عالمي. استخدم مكتبات مثل Moment.js أو Luxon لمعالجة التاريخ/الوقت أو، ويفضل، أحدث معالجة كائن التاريخ المضمنة في Javascript مع إدراك المنطقة الزمنية. قم بتخزين التواريخ/الأوقات بتنسيق UTC في قاعدة البيانات الخاصة بك وقم بتحويلها إلى المنطقة الزمنية المحلية للمستخدم عند عرضها.
- التعامل بالعملة: إذا كان تطبيقك يتعامل مع المعاملات المالية، فتعامل مع العملات بشكل صحيح. استخدم تنسيق العملة المناسب وفكر في دعم عملات متعددة. تأكد من الحفاظ على بياناتك بشكل متسق ودقيق.
- الامتثال القانوني والتنظيمي: كن على دراية بالمتطلبات القانونية والتنظيمية في مختلف البلدان أو المناطق (على سبيل المثال، GDPR، CCPA). قم بتنفيذ التدابير اللازمة للامتثال لهذه اللوائح.
- إمكانية الوصول: تأكد من إمكانية وصول تطبيقك إلى المستخدمين ذوي الإعاقة. اتبع إرشادات إمكانية الوصول مثل WCAG (إرشادات إمكانية الوصول إلى محتوى الويب).
- المراقبة والتنبيه: قم بتنفيذ مراقبة وتنبيه شاملين للكشف عن المشكلات والاستجابة لها بسرعة. راقب أداء الخادم وأخطاء التطبيقات والتهديدات الأمنية.
الخلاصة
يعد إتقان أنماط البرمجيات الوسيطة المتقدمة أمرًا بالغ الأهمية لبناء تطبيقات Express.js قوية وآمنة وقابلة للتطوير. باستخدام هذه الأنماط بفعالية، يمكنك إنشاء تطبيقات ليست وظيفية فحسب، بل قابلة للصيانة ومناسبة أيضًا لجمهور عالمي. تذكر أن تعطي الأولوية للأمان والأداء وقابلية الصيانة طوال عملية التطوير الخاصة بك. من خلال التخطيط والتنفيذ الدقيقين، يمكنك الاستفادة من قوة البرمجيات الوسيطة Express.js لبناء تطبيقات ويب ناجحة تلبي احتياجات المستخدمين في جميع أنحاء العالم.
القراءة الإضافية: