تعلم كيفية الاستفادة من مسارات API في Next.js لبناء واجهات خلفية بدون خادم مباشرة داخل تطبيق Next.js الخاص بك. يغطي هذا الدليل كل شيء بدءًا من الإعداد الأساسي إلى التقنيات المتقدمة للتعامل مع المصادقة وتخزين البيانات والمزيد.
مسارات واجهة برمجة التطبيقات (API) في Next.js: بناء الواجهة الخلفية بسهولة
لقد أحدث Next.js ثورة في تطوير الواجهات الأمامية بميزاته القوية وهيكله البديهي. ولكن هل تعلم أنه يمكنه أيضًا تبسيط تطوير الواجهات الخلفية بشكل كبير؟ تتيح لك مسارات API في Next.js إنشاء نقاط نهاية API بدون خادم مباشرة داخل تطبيق Next.js الخاص بك، مما يلغي الحاجة إلى خادم خلفي منفصل في كثير من الحالات. سيرشدك هذا الدليل الشامل خلال عملية بناء واجهة خلفية قوية وقابلة للتطوير باستخدام مسارات API في Next.js.
ما هي مسارات API في Next.js؟
مسارات API هي دوال بدون خادم تقوم بإنشائها داخل دليل /pages/api
في مشروع Next.js الخاص بك. تتعامل هذه الدوال مع طلبات HTTP الواردة وتعيد استجابات، تمامًا مثل واجهة API الخلفية التقليدية. الفرق الرئيسي هو أنها تُنشر كدوال بدون خادم، مما يعني أنك لا تحتاج إلى إدارة الخوادم أو البنية التحتية.
فكر فيها كدوال خلفية خفيفة الوزن وعند الطلب، مدمجة بسلاسة مع الواجهة الأمامية لـ Next.js.
فوائد استخدام مسارات API في Next.js
- تطوير مبسط: اكتب كود الواجهة الأمامية والخلفية في نفس المشروع، باستخدام JavaScript أو TypeScript. لا مزيد من التنقل بين المشاريع والتقنيات المختلفة.
- بنية بدون خادم: استفد من قابلية التوسع والموثوقية وفعالية التكلفة للحوسبة بدون خادم. ادفع فقط مقابل الموارد التي تستهلكها.
- نشر سهل: انشر تطبيقك بالكامل (الواجهة الأمامية والخلفية) بأمر واحد باستخدام منصات مثل Vercel أو Netlify.
- أمان مدمج: يوفر Next.js ومنصات الحوسبة بدون خادم ميزات أمان مدمجة لحماية نقاط نهاية API الخاصة بك.
- أداء مُحسَّن: يمكن نشر مسارات API بالقرب من المستخدمين، مما يقلل من زمن الوصول ويحسن الأداء، وهو أمر مفيد بشكل خاص للمستخدمين على مستوى العالم.
- إعادة استخدام الكود: شارك الكود بين الواجهة الأمامية والخلفية، مما يقلل من تكرار الكود ويحسن قابلية الصيانة.
البدء مع مسارات API في Next.js
دعنا ننشئ مسار API بسيطًا يعيد استجابة JSON. أولاً، تأكد من أن لديك مشروع Next.js مُعدًا. إذا لم يكن كذلك، أنشئ واحدًا باستخدام:
npx create-next-app my-app
cd my-app
الآن، أنشئ ملفًا باسم hello.js
داخل دليل /pages/api
:
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
يعرّف هذا الكود مسار API بسيطًا يستجيب بكائن JSON يحتوي على الاسم "John Doe". للوصول إلى مسار API هذا، ابدأ خادم التطوير الخاص بـ Next.js:
npm run dev
ثم، افتح متصفحك وانتقل إلى http://localhost:3000/api/hello
. يجب أن ترى استجابة JSON التالية:
{"name": "John Doe"}
فهم معالج مسار API
تتلقى دالة handler
في مسار API الخاص بك وسيطين:
req
: نسخة منhttp.IncomingMessage
، والتي تحتوي على معلومات حول الطلب الوارد، مثل طريقة الطلب، والترويسات، والجسم.res
: نسخة منhttp.ServerResponse
، والتي تتيح لك إرسال استجابة مرة أخرى إلى العميل.
يمكنك استخدام هذه الكائنات للتعامل مع أنواع مختلفة من الطلبات، وقراءة البيانات من جسم الطلب، وتعيين ترويسات الاستجابة، وإرسال أنواع مختلفة من الاستجابات.
التعامل مع طرق HTTP المختلفة
يمكنك استخدام خاصية req.method
لتحديد طريقة HTTP للطلب الوارد والتعامل مع الطرق المختلفة بناءً على ذلك. على سبيل المثال:
// pages/api/method.js
export default function handler(req, res) {
if (req.method === 'GET') {
// التعامل مع طلب GET
res.status(200).json({ message: 'This is a GET request' })
} else if (req.method === 'POST') {
// التعامل مع طلب POST
res.status(200).json({ message: 'This is a POST request' })
} else {
// التعامل مع الطرق الأخرى
res.status(405).json({ message: 'Method Not Allowed' })
}
}
في هذا المثال، يتعامل مسار API مع طلبات GET و POST. إذا كانت طريقة الطلب GET، فإنه يستجيب بكائن JSON يحتوي على الرسالة "This is a GET request". إذا كانت طريقة الطلب POST، فإنه يستجيب بكائن JSON يحتوي على الرسالة "This is a POST request". إذا كانت طريقة الطلب أي شيء آخر، فإنه يستجيب بخطأ 405 Method Not Allowed.
قراءة البيانات من جسم الطلب
بالنسبة لطلبات POST و PUT و PATCH، غالبًا ما تحتاج إلى قراءة البيانات من جسم الطلب. يوفر Next.js دعمًا مدمجًا لتحليل أجسام الطلبات بصيغة JSON و URL-encoded. لتحليل جسم طلب JSON، يمكنك استخدام خاصية req.body
. على سبيل المثال:
// pages/api/post.js
export default async function handler(req, res) {
if (req.method === 'POST') {
const { name, email } = req.body
// معالجة البيانات
console.log('Name:', name)
console.log('Email:', email)
res.status(200).json({ message: 'Data received successfully' })
} else {
res.status(405).json({ message: 'Method Not Allowed' })
}
}
لاختبار مسار API هذا، يمكنك استخدام أداة مثل Postman أو curl لإرسال طلب POST مع جسم JSON:
curl -X POST -H "Content-Type: application/json" -d '{"name": "Jane Doe", "email": "jane.doe@example.com"}' http://localhost:3000/api/post
تعيين ترويسات الاستجابة
يمكنك استخدام طريقة res.setHeader()
لتعيين ترويسات الاستجابة. هذا مفيد لتعيين نوع المحتوى، والتحكم في التخزين المؤقت، وغيرها من المعلومات الهامة. على سبيل المثال:
// pages/api/headers.js
export default function handler(req, res) {
res.setHeader('Content-Type', 'application/json')
res.setHeader('Cache-Control', 's-maxage=3600')
res.status(200).json({ message: 'Hello, world!' })
}
في هذا المثال، يعيّن مسار API ترويسة Content-Type
إلى application/json
، مما يشير إلى أن الاستجابة هي كائن JSON. كما أنه يعيّن ترويسة Cache-Control
إلى s-maxage=3600
، مما يخبر المتصفح وشبكة توصيل المحتوى (CDN) بتخزين الاستجابة مؤقتًا لمدة تصل إلى ساعة واحدة.
معالجة الأخطاء
من المهم التعامل مع الأخطاء بأناقة في مسارات API الخاصة بك. يمكنك استخدام كتل try-catch لالتقاط الاستثناءات وإرسال استجابات خطأ مناسبة إلى العميل. على سبيل المثال:
// pages/api/error.js
export default async function handler(req, res) {
try {
// محاكاة خطأ
throw new Error('Something went wrong')
} catch (error) {
console.error(error)
res.status(500).json({ message: 'Internal Server Error' })
}
}
في هذا المثال، يحاكي مسار API خطأً عن طريق طرح كائن Error
جديد. تلتقط كتلة catch الخطأ، وتسجله في وحدة التحكم، وترسل استجابة خطأ 500 Internal Server Error إلى العميل. ضع في اعتبارك استخدام نظام تسجيل قوي مثل Sentry أو Datadog لبيئات الإنتاج.
الاتصال بقاعدة بيانات
أحد أكثر حالات الاستخدام شيوعًا لمسارات API هو الاتصال بقاعدة بيانات. تتكامل مسارات API في Next.js بسلاسة مع قواعد بيانات مختلفة، بما في ذلك:
- MongoDB: قاعدة بيانات NoSQL شائعة مناسبة تمامًا للبيانات المرنة وغير المهيكلة.
- PostgreSQL: قاعدة بيانات علائقية قوية ومفتوحة المصدر تشتهر بموثوقيتها وسلامة بياناتها.
- MySQL: قاعدة بيانات علائقية أخرى شائعة ومفتوحة المصدر تستخدم على نطاق واسع لتطبيقات الويب.
- Firebase: منصة سحابية توفر قاعدة بيانات في الوقت الفعلي وخدمات أخرى.
- FaunaDB: قاعدة بيانات بدون خادم مصممة للتطبيقات العالمية.
إليك مثال على كيفية الاتصال بقاعدة بيانات MongoDB في مسار API لـ Next.js:
// pages/api/mongodb.js
import { MongoClient } from 'mongodb'
const uri = process.env.MONGODB_URI
const options = {}
let client
let clientPromise
if (!process.env.MONGODB_URI) {
throw new Error('Please add your Mongo URI to .env.local')
}
if (process.env.NODE_ENV === 'development') {
// في وضع التطوير، استخدم متغيرًا عامًا حتى يتم الاحتفاظ بالقيمة
// عبر عمليات إعادة تحميل الوحدة النمطية الناتجة عن HMR (استبدال الوحدة النمطية السريع).
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options)
global._mongoClientPromise = client.connect()
}
clientPromise = global._mongoClientPromise
} else {
// في وضع الإنتاج، من الأفضل عدم استخدام متغير عام.
client = new MongoClient(uri, options)
clientPromise = client.connect()
}
// تصدير وعد MongoClient على مستوى الوحدة. من خلال القيام بذلك في
// وحدة منفصلة، يمكن إعادة استخدام العميل بأمان عبر دوال متعددة.
// انظر: https://github.com/vercel/next.js/blob/canary/examples/with-mongodb/lib/mongodb.js
export default async function handler(req, res) {
try {
const client = await clientPromise
const db = client.db(process.env.MONGODB_DB)
const collection = db.collection('users')
const users = await collection.find({}).toArray()
res.status(200).json({ users })
} catch (e) {
console.error(e)
res.status(500).json({ message: 'Failed to fetch users' })
}
}
قبل تشغيل هذا الكود، تأكد من تثبيت حزمة mongodb
:
npm install mongodb
تحتاج أيضًا إلى تعيين متغيرات البيئة MONGODB_URI
و MONGODB_DB
. يجب تحديد هذه المتغيرات في ملف .env.local
الخاص بك (أو إعدادات متغيرات البيئة لمزود الاستضافة الخاص بك للإنتاج). يحتوي MONGODB_URI
على سلسلة الاتصال بقاعدة بيانات MongoDB الخاصة بك، ويحدد MONGODB_DB
اسم قاعدة البيانات.
المصادقة والترخيص
تعد حماية مسارات API الخاصة بك أمرًا بالغ الأهمية للأمان. يمكن تأمين مسارات API في Next.js باستخدام تقنيات مصادقة وترخيص مختلفة، بما في ذلك:
- رموز الويب JSON (JWT): معيار لنقل المعلومات بشكل آمن بين الأطراف ككائن JSON.
- مفاتيح API: طريقة بسيطة لتقييد الوصول إلى نقاط نهاية API الخاصة بك.
- OAuth: بروتوكول تفويض يسمح للمستخدمين بمنح تطبيقات الطرف الثالث إمكانية الوصول إلى مواردهم دون مشاركة بيانات اعتمادهم.
- NextAuth.js: حل مصادقة كامل ومفتوح المصدر لتطبيقات Next.js.
إليك مثال على كيفية حماية مسار API باستخدام مصادقة JWT:
// pages/api/protected.js
import jwt from 'jsonwebtoken'
const secret = process.env.JWT_SECRET
export default function handler(req, res) {
const token = req.headers.authorization?.split(' ')[1]
if (!token) {
return res.status(401).json({ message: 'Unauthorized' })
}
try {
const decoded = jwt.verify(token, secret)
// يحتوي كائن "decoded" على معلومات المستخدم المضمنة في الرمز
// على سبيل المثال: const userId = decoded.userId;
// متابعة معالجة الطلب
res.status(200).json({ message: 'Protected resource accessed successfully' })
} catch (error) {
return res.status(401).json({ message: 'Invalid token' })
}
}
قبل تشغيل هذا الكود، تأكد من تثبيت حزمة jsonwebtoken
:
npm install jsonwebtoken
تحتاج أيضًا إلى تعيين متغير البيئة JWT_SECRET
. يجب أن يكون هذا مفتاحًا سريًا قويًا تم إنشاؤه عشوائيًا ويستخدم لتوقيع والتحقق من رموز JWT. قم بتخزين هذا بشكل آمن ولا تكشف عنه أبدًا في كود جانب العميل الخاص بك.
البرمجيات الوسيطة (Middleware)
على الرغم من أن Next.js لا يقدم برمجيات وسيطة تقليدية لمسارات API بنفس طريقة Express.js، يمكنك تحقيق وظائف مماثلة عن طريق تغليف معالجات مسار API الخاصة بك بدوال قابلة لإعادة الاستخدام. هذا يتيح لك أداء مهام مثل:
- المصادقة: التحقق من بيانات اعتماد المستخدم قبل السماح بالوصول إلى نقاط نهاية API.
- الترخيص: التحقق مما إذا كان لدى المستخدم الأذونات اللازمة لتنفيذ إجراء معين.
- التسجيل: تسجيل الطلبات الواردة والاستجابات الصادرة لأغراض التدقيق وتصحيح الأخطاء.
- التحقق من الصحة: التحقق من صحة بيانات الطلب لضمان أنها تلبي معايير محددة.
- تحديد المعدل: حماية واجهة برمجة التطبيقات الخاصة بك من إساءة الاستخدام عن طريق تحديد عدد الطلبات التي يمكن للمستخدم إجراؤها خلال فترة زمنية معينة.
إليك مثال على كيفية إنشاء برمجية وسيطة بسيطة للتسجيل:
// utils/middleware.js
export function withLogging(handler) {
return async function(req, res) {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`)
return handler(req, res)
}
}
لاستخدام هذه البرمجية الوسيطة، ما عليك سوى تغليف معالج مسار API الخاص بك بالدالة withLogging
:
// pages/api/logged.js
import { withLogging } from '../../utils/middleware'
async function handler(req, res) {
res.status(200).json({ message: 'This request was logged' })
}
export default withLogging(handler)
أفضل الممارسات لبناء مسارات API في Next.js
- اجعل مسارات API الخاصة بك صغيرة ومركزة. يجب أن يتعامل كل مسار API مع مهمة أو مورد محدد.
- استخدم متغيرات البيئة للبيانات الحساسة. لا تقم أبدًا بتضمين الأسرار أو مفاتيح API بشكل مباشر في الكود الخاص بك.
- تحقق من صحة بيانات الطلب لمنع الثغرات الأمنية. استخدم مكتبة مثل Joi أو Yup للتحقق من صحة أجسام الطلبات.
- تعامل مع الأخطاء بأناقة وقدم رسائل خطأ مفيدة. استخدم كتل try-catch وسجل الأخطاء في موقع مركزي.
- استخدم التخزين المؤقت لتحسين الأداء. قم بتخزين البيانات التي يتم الوصول إليها بشكل متكرر لتقليل الحمل على قاعدة البيانات.
- راقب مسارات API الخاصة بك من حيث الأداء والأخطاء. استخدم أداة مراقبة مثل Sentry أو Datadog لتتبع صحة واجهة برمجة التطبيقات الخاصة بك.
- وثّق مسارات API الخاصة بك باستخدام أداة مثل Swagger أو OpenAPI. هذا يسهل على المطورين الآخرين استخدام واجهة برمجة التطبيقات الخاصة بك.
- ضع في اعتبارك استخدام TypeScript لسلامة الأنواع. يمكن أن يساعدك TypeScript في اكتشاف الأخطاء مبكرًا وتحسين قابلية صيانة الكود الخاص بك.
- فكر في التدويل (i18n) منذ البداية. إذا كان سيتم استخدام تطبيقك من قبل مستخدمين من بلدان مختلفة، فصمم مسارات API الخاصة بك لدعم لغات وعملات متعددة. على سبيل المثال، قد تحتاج نقاط نهاية API للتجارة الإلكترونية إلى التعامل مع معدلات ضرائب وتكاليف شحن مختلفة بناءً على موقع المستخدم.
- نفّذ تكوين CORS (مشاركة الموارد عبر المصادر) بشكل صحيح. هذا أمر بالغ الأهمية عندما يتم الوصول إلى واجهة برمجة التطبيقات الخاصة بك من نطاق مختلف عن تطبيق Next.js الخاص بك. قم بتكوين CORS بعناية للسماح فقط للأصول المصرح بها بالوصول إلى موارد API الخاصة بك.
تقنيات متقدمة
المهام الخلفية
بالنسبة للمهام طويلة الأمد التي لا ينبغي أن تمنع استجابة API، ضع في اعتبارك استخدام المهام الخلفية. يمكنك استخدام مكتبات مثل BullMQ أو Bree لإدارة مهامك الخلفية ومعالجتها بشكل غير متزامن.
WebSockets
للتطبيقات في الوقت الفعلي، يمكنك استخدام WebSockets في مسارات API الخاصة بـ Next.js. تسهل مكتبات مثل Socket.IO و ws إنشاء اتصالات مستمرة بين العميل والخادم.
GraphQL
إذا كنت بحاجة إلى طريقة أكثر مرونة وكفاءة لجلب البيانات، ففكر في استخدام GraphQL. يمكنك استخدام مكتبات مثل Apollo Server أو Yoga لإنشاء نقطة نهاية GraphQL API في تطبيق Next.js الخاص بك.
الخاتمة
توفر مسارات API في Next.js طريقة قوية ومريحة لبناء واجهات خلفية بدون خادم مباشرة داخل تطبيق Next.js الخاص بك. من خلال الاستفادة من مزايا البنية بدون خادم، يمكنك تبسيط التطوير وتحسين الأداء وتقليل التكاليف. سواء كنت تبني نموذج اتصال بسيطًا أو منصة تجارة إلكترونية معقدة، يمكن أن تساعدك مسارات API في Next.js على إنشاء واجهة خلفية قوية وقابلة للتطوير بسهولة. من خلال فهم قوي للأساسيات وتطبيق أفضل الممارسات، يمكنك الاستفادة من هذه الأداة القوية لإنشاء تطبيقات فعالة وآمنة ويمكن الوصول إليها عالميًا.