Next.js/api routes

من موسوعة حسوب
< Next.js
مراجعة 03:52، 23 مايو 2022 بواسطة ابراهيم-الخضور (نقاش | مساهمات) (أنشأ الصفحة ب'= المسارات إلى الواجهة البرمجية API في Next.js = تٌعد مسارات API طريقة لبناء الواجهة البرمجية لتطبيق...')
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث

المسارات إلى الواجهة البرمجية API في Next.js

تٌعد مسارات API طريقة لبناء الواجهة البرمجية لتطبيقك باستخدام Next.js . إذ يُربط كل ملف ضمن المجلد pages/api بالمسار */api/ ويُعامل كوصلة API (نقطة اتصال مع الواجهة البرمجية) بدلًا من كونه صفحة page. تمثّل هذه الوصلات تجمّعات bundles في جانب الخادم فقطولن تزيد حجم تجميعة التطبيق من جانب العميل. يعيد مسار API التالي pages/api/user.js على سبيل المثال استجابة بصيغة json مع رمز الحالة 200 :

export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' })
}

ولكي يعمل مسار API لا بد من تصدير دالة على أنها افتراضية default (مثل الدالة handler في المثال السابق) ومن ثم تستقبل المعاملات التالية:

  • req: يضم نسخة عن الكائن http.IncomingMessage بالإضافة إلى بعض الأدوات الوسطية المبنية مسبقًا (سنتعرف عليها لاحقًا في هذه الصفحة).
  • res: يضم نسخة عن الكائن http.ServerResponse بالإضافة إلى دوال مساعدة (سنتعرف عليها لاحقًا في هذه الصفحة).

يمكنك استخدام الكائن req.method ضمن معالج الطلب request handler إن أردت التعامل مع الأنواع المختلفة لطلبات HTTP في مسار API. إليك مثالًا:

export default function handler(req, res) {
  if (req.method === 'POST') {
    // POST يعالج طلب من النوع 
  } else {
    // يعالج بقية أنواع الطلبات
  }
}

حالات الاستخدام مسارت API في Next.js

يمكنك بناء الواجهة البرمجية API بأكملها لمشروعك الجديد باستخدام مسارات API. فإن كان لديك واجهة برمجية جاهزة، لا حاجة عندها لتوجيه الاستدعاءات إليها من خلال مسارات API. إليك بعض الحالات التي يمكن استخدام مسارات API فيها:

  • إخفاء عنوان URL عن خدمة خارجية (مثال: api/secret/ بدلًا عن https://company.com/secret-url)
  • استخدام متغيرات بيئة ضمن الخادم للولوج الآمن إلى خدمات خارجية.

التحفظات على استخدام مسارت API في Next.js

  • لا تحدد مسارات API ترويسات مشاركة الموارد ذات الصل المختلط CORS، أي أنها افتراضيًا للموارد ذات الأصل المشترك same-origin فقط. يمكنك التحكم بهذا السلوك عبر تغليف معالج الطلب باستخدام أداة CORS وسطية.
  • لا يمكن استخدام مسارات API مع next export.

مسارات API ديناميكية

تدعم مسارات API الوجهات الديناميكية وتخضع لجميع قواعد تسمية الملفات التي تستخدم مع الصفحات pages. فشيفرة مسار API للوجهة pages/api/post/[pid].js هي كالتالي:

export default function handler(req, res) {
  const { pid } = req.query
  res.end(`Post: ${pid}`)
}

الصفحة index ومسارات API الديناميكية

تهيئ المسارات بما يتطابق مع معايير REST (أو كما يُعرف RESTful) بالشكل التالي الأكثر شيوعًا:

  • GET api/posts: يُحضر قائمة بالمنشورات التي قد تكون مرتبة في صفحات.
  • GET api/posts/12345: يُحضر المنشور ذو المعرّف 12345.

يمكن نمذجة هذا الأمثلة كما يلي:

  • الخيار الأول:
    • api/posts.js/
    • api/posts/[postId].js/
  • الخيار الثاني:
    • api/posts/index.js/
    • api/posts/[postId].js/

إن النموذجين السابقين متكافئين. وهنالك خيار ثالث يستخدم فقط النموذج api/posts/[postId].js/ لكنه لا يصلح لحالتنا لأن المسارات الديناميكية (بما فيها التقاط جميع المسارات Catch-all routes) لا تمتلك حالة غير محددة undefined وبالتالي لن يتمكن GET api/posts من مطابقة الوجهة api/posts/[postId].js/ أبدًا.

التقاط جميع الوجهات من خلال مسار API الديناميكي

بالإمكان توسعة مسارات API الديناميكية لمطابقة كل المسارات وذلك بإضافة ثلاث نقاط (...) داخل القوسين المربعين. إليك مثالًا:

  • تطابق الوجهة pages/api/post/[...slug].js المسار api/post/a/ كما تطابق api/post/a/b/ و api/post/a/b/c/ وهكذا. بإمكانك طبعًا اختيار أي اسم بدلًا من slug مثل [param...].

تُرسل معاملات البحث كمعاملات استعلام ( slug مثال على ذلك) إلى الصفحة، وتشكل المعاملات دائمًا مصفوفة. وبالتالي سيكون كائن الاستعلام عن المسار api/post/a/ مثلًا هو:

{ "slug": ["a"] }

في حالة api/post/a/b/ وأية مسارات مطابقة أخرى، ستُضاف البارمترات الجديدة إلى المصفوفة كالتالي:

{ "slug": ["a", "b"] }

يبدو مسار API إلى الوجهة pages/api/post/[...slug].js كالتالي:

export default function handler(req, res) {
  const { slug } = req.query
  res.end(`Post: ${slug.join(', ')}`)
}

وهكذا سيكون النص Post: a, b, c هو الرد على الطلب api/post/a/b/c/.

التقاط جميع الوجهات بشكل اختياري

يمكن التقاط جميع الوجهات اختياريًا بإضافة المعامل بين قوسين مربعين مزدوجين مثل ([[...slug]]). إذ ستطابق الوجهة pages/api/post/[[...slug]].js مثلًا المسارات api/post/ و api/post/a/ و api/post/a/b/ وهكذا.

إن الاختلاف الرئيسي بين التقاط جميع الوجهات والتقاط جميع الوجهات اختياريًا هو أن الالتقاط الاختياري سيطابق أيضًا المسارات التي لا تضم معامل البحث (المسار api/post/ مثالًا).

سيكون كائن الاستعلام query التالي:

{ } //`/api/post` سيحصل على المسار 
{ "slug": ["a"] } //(مصفوفة وحيد العنصر) `/api/post/a` سيحصل على المسار 
{ "slug": ["a", "b"] } //(مصفوفة متعددة العناصر) `/api/post/a/b` سيحصل على

تحفظات على المسارات الديناميكية في Next.js

  • لوجهات API المحددة مسبقًا الأفضلية على الوجهات الدينياميكية و التي لها الأفضلية على جميع المسارات الملتقطة. إليك بعض الأمثلة:
    • pages/api/post/create.js يتطابق مع api/post/create/.
    • pages/api/post/[pid].js يتطابق مع api/post/1/ و api/post/abc/ وليس مع api/post/create/.
    • pages/api/post/[...slug].js يتطابق مع api/post/1/2/ و /api/post/a/b/c/ وليس مع api/post/create/ و api/post/abc/.

استخدام أدوات API الوسطية في Next.js

تزوّدك مسارات API بأدوات وسطية middleware مدمجة تحلل الطلب الوارد (req) هي:

  • req.cookies: وهي كائن يتضمن ملفات تعريف الارتباط التي يرسلها الطلب. قيمته الافتراضية {}.
  • req.query: وهي كائن يتضمن نص الاستعلام، وقيمته الافتراضية {}.
  • req.body: وهي كائن يضم جسم الطلب يحلل وفقًا للخاصية content-type أو يأخذ القيمة غن لم يُرسل جسم الطلب null.

إعدادات مخصصة

يمكن لمسار API أن يُصدّر كائن التهيئة config ليغيّر التهيئة الافتراضية وهي:

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '1mb',
    },
  },
}

يضم الكائن api كل الإعدادات المتاحة لمسار API، ويُفعَّل الخيار bodyParser (تحليل جسم الطلب) تلقائيًا. لكن بإمكانك تعطيله بضبط قيمته على false وذلك إن أردت استهلاك جسم الطلب عبر خيار النقل المستمر لبياناته Stream أو بواسطة الخيار raw-body. إحدى الحالات التي يُعطَّل فيها الخيار bodyParsing هي الحالة التي نريد فيها التحقق من القيمة الخام لجسم طلب خطاف ويب webhook مصدره GitHub مثلًا:

export const config = {
  api: {
    bodyParser: false,
  },
}

تعطي القيمة bodyParser.sizeLimit الحجم الأقصى المسموح للجسم المُحلل بأية صيغة تدعمها المكتبة bytes كالتالي:

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '500kb',
    },
  },
}

تخبر الراية externalResolver الخادم إن المسار سيُعالج من قبل محلل خارجي مثل express أو connect . بتفعيل هذه الراية سيوقف التنبيهات التي سببها الطلبات غير المحللة unresolved.