10 أفضل الممارسات لكتابة واجهات برمجة التطبيقات Node.js REST

نغطي في هذه المقالة أفضل الممارسات لكتابة واجهات برمجة التطبيقات Node.js REST ، بما في ذلك موضوعات مثل تسمية مساراتك والمصادقة واختبار الصندوق الأسود واستخدام رؤوس ذاكرة التخزين المؤقت المناسبة لهذه الموارد.

أحد أكثر حالات الاستخدام شيوعًا لـ Node.js هي كتابة واجهات برمجة التطبيقات (RESTful) باستخدامه. ومع ذلك ، على الرغم من أننا نساعد عملائنا على العثور على مشكلات في تطبيقاتهم باستخدام Trace ، فإننا نواجه أداة مراقبة Node.js باستمرار لأن المطورين لديهم الكثير من المشاكل مع REST APIs.

آمل أن تساعد أفضل الممارسات التي نستخدمها في RisingStack:

# 1: استخدام طرق HTTP وطرق API

تخيل أنك تقوم بإنشاء واجهة برمجة تطبيقات Node.js RESTful لإنشاء المستخدمين أو تحديثهم أو استعادتهم أو حذفهم. بالنسبة لهذه العمليات ، يحتوي HTTP بالفعل على مجموعة الأدوات الكافية: POST أو PUT أو GET أو PATCH أو DELETE.

كأفضل الممارسات ، يجب أن تستخدم طرق واجهة برمجة التطبيقات دائمًا الأسماء كمعرفات المورد. عند الحديث عن موارد المستخدم ، يمكن أن يبدو التوجيه كما يلي:

  • POST / user أو PUT / user: / id لإنشاء مستخدم جديد ،
  • الحصول على / مستخدم لاسترداد قائمة المستخدمين ،
  • الحصول على / user /: id لاسترداد مستخدم ،
  • PATCH / user /: id لتعديل سجل مستخدم حالي ،
  • DELETE / user /: id لإزالة مستخدم.

# 2: استخدام رموز حالة HTTP بشكل صحيح

إذا حدث خطأ ما أثناء تقديم الطلب ، يجب عليك تعيين رمز الحالة الصحيح لذلك في الاستجابة:

  • 2xx ، إذا كان كل شيء على ما يرام ،
  • 3xx ، إذا تم نقل المورد ،
  • 4xx ، إذا تعذر تلبية الطلب بسبب خطأ في العميل (مثل طلب مورد غير موجود) ،
  • 5xx ، إذا حدث خطأ ما على جانب واجهة برمجة التطبيقات (مثل حدث استثناء).

إذا كنت تستخدم Express ، فسيكون إعداد رمز الحالة سهلًا مثل res.status (500). أرسل ({error: 'حدث خطأ داخلي في الخادم'}). وبالمثل مع Restify: res.status (201).

للحصول على قائمة كاملة ، تحقق من قائمة رموز حالة HTTP

# 3: استخدم رؤوس HTTP لإرسال بيانات التعريف

لإرفاق بيانات التعريف حول الحمولة التي أنت بصدد إرسالها ، استخدم رؤوس HTTP. يمكن أن تكون مثل هذه الرؤوس معلومات حول:

  • ترقيم الصفحات،
  • الحد من معدل ،
  • أو المصادقة.

يمكن العثور على قائمة برموز HTTP الموحدة هنا.

إذا كنت بحاجة إلى تعيين أي بيانات وصفية مخصصة في الرؤوس الخاصة بك ، فقد كان من أفضل الممارسات أن تسبقها بـ X. على سبيل المثال ، إذا كنت تستخدم رموز CSRF ، فقد كانت طريقة شائعة (ولكن غير قياسية) لتسمية X-Csrf. -Token. ولكن مع RFC 6648 حصلوا على إهمال. يجب أن تبذل واجهات برمجة التطبيقات الجديدة قصارى جهدها لعدم استخدام أسماء الرؤوس التي يمكن أن تتعارض مع التطبيقات الأخرى. على سبيل المثال ، يقوم OpenStack بادئة رؤوسه باستخدام OpenStack:

أوبن ستاك-الهوية-الحساب-ID
أوبن ستاك شبكات المضيف-الاسم
أوبن ستاك-كائن التخزين-سياسة

لاحظ أن معيار HTTP لا يحدد أي حد للحجم على الرؤوس ؛ ومع ذلك ، يفرض Node.js (حتى كتابة هذه المقالة) حد حجم 80 كيلو بايت على كائن رؤوس لأسباب عملية.

"لا تسمح للحجم الكلي لرؤوس HTTP (بما في ذلك سطر الحالة) بتجاوز HTTP_MAX_HEADER_SIZE. هذا الفحص هنا لحماية الدمج من هجمات الحرمان من الخدمة حيث يقوم المهاجم بإطعامنا برأس لا ينتهي إلى أن يحتفظ الدمج به مؤقتًا. "
من محلل HTTP Node.js

# 4: اختر الإطار المناسب لواجهة برمجة التطبيقات Node.js REST الخاصة بك

من المهم اختيار الإطار الذي يناسب حالة الاستخدام الخاصة بك أكثر من غيره.

اكسبرس ، كوا أو هابي

يمكن استخدام Express و Koa و Hapi لإنشاء تطبيقات المستعرض ، وبالتالي ، فهي تدعم templating والعرض - فقط لتسمية بعض الميزات. إذا كان التطبيق الخاص بك يحتاج إلى توفير الجانب الذي يواجه المستخدم أيضًا ، فمن المنطقي أن يوافق عليه.

Restify

من ناحية أخرى ، تركز Restify على مساعدتك في إنشاء خدمات REST. إنه موجود للسماح لك ببناء خدمات API "الصارمة" التي يمكن صيانتها ويمكن ملاحظتها. Restify يأتي أيضًا مع دعم DTrace التلقائي لجميع معالجاتك.

يستخدم Restify في الإنتاج في التطبيقات الرئيسية مثل npm أو Netflix.

# 5: Black-Box اختبار واجهات برمجة التطبيقات Node.js REST

واحدة من أفضل الطرق لاختبار واجهات برمجة تطبيقات REST هي معاملتها كمربعات سوداء.

إن اختبار الصندوق الأسود هو طريقة للاختبار حيث يتم فحص وظائف التطبيق دون معرفة بنياته الداخلية أو أعماله. لذلك لا يتم الاستهزاء بأي من التبعيات أو عناقيدها ، ولكن يتم اختبار النظام ككل.

إحدى الوحدات النمطية التي يمكنها مساعدتك في اختبار الصندوق الأسود لـ Node.js REST APIs هي اختبار ممتاز.

يمكن إجراء حالة اختبار بسيطة تتحقق مما إذا كان المستخدم قد تم إرجاعه باستخدام mocha runner test كما يلي:

طلب const = مطلوب ("اختبار ممتاز")
 
صف ('GET / user /: id' ، function () {
  ذلك ('إرجاع مستخدم' ، وظيفة () {
    // أحدث إصدارات المخاوي تقبل الوعود كذلك
    طلب إرجاع (تطبيق)
      . احصل على ( '/ المستخدم)
      .set ("قبول" ، "application / json")
      .توقع (200 ، {
        المعرف: '1' ،
        الاسم: جون ماث
      }، فعله)
  })
})

قد تسأل: كيف يتم ملء البيانات في قاعدة البيانات التي تخدم REST API؟

بشكل عام ، من الأفضل لكتابة اختباراتك بطريقة تجعلها قليلة من الافتراضات حول حالة النظام قدر الإمكان. ومع ذلك ، في بعض السيناريوهات ، يمكنك أن تجد نفسك في مكان ما عندما تحتاج إلى معرفة حالة النظام بالضبط ، حتى تتمكن من تقديم تأكيدات وتحقيق تغطية اختبار أعلى.

بناءً على احتياجاتك ، يمكنك ملء قاعدة البيانات ببيانات الاختبار بإحدى الطرق التالية:

  • قم بتشغيل سيناريوهات اختبار الصندوق الأسود على مجموعة فرعية معروفة من بيانات الإنتاج ،
  • ملء قاعدة البيانات مع البيانات وضعت قبل أن يتم تشغيل حالات الاختبار.

بالطبع ، لا يعني اختبار الصندوق الأسود أنك لست مضطرًا للقيام باختبار الوحدة ، ولكن لا يزال يتعين عليك كتابة اختبارات الوحدات الخاصة بواجهات برمجة التطبيقات.

# 6: هل JWT ، مصادقة عديمي الجنسية

نظرًا لأن REST APIs يجب أن تكون بلا جنسية ، وكذلك طبقة المصادقة. لهذا ، JWT (JSON Web Token) مثالية.

يتكون JWT من ثلاثة أجزاء:

  • رأس ، يحتوي على نوع الرمز المميز وخوارزمية التجزئة
  • حمولة ، تحتوي على المطالبات
  • التوقيع (JWT لا يشفر الحمولة ، فقط يوقعها!)

إضافة المصادقة المستندة إلى JWT إلى التطبيق الخاص بك واضحة جدًا:

const koa = مطلوب ('koa')
const jwt = require ('koa-jwt')
التطبيق const = koa ()
app.use (JWT ({
  سر: "سري للغاية"
}))
// الوسيطة المحمية
app.use (دالة * () {
  // محتوى الرمز المميز سيكون متاحًا على this.state.user
  هذا.
    سر: 42
  }
})

بعد ذلك ، يتم حماية نقاط النهاية API مع JWT. للوصول إلى نقاط النهاية المحمية ، يجب عليك توفير الرمز المميز في حقل رأس التخويل.

curl - header "Authorization: Bearer eyJhbGciOiJIUZI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwI
iwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30
RMHrHDcEfxjoYZgeFONFh7HgQ "my-website.com

شيء واحد يمكن أن تلاحظه هو أن وحدة JWT لا تعتمد على أي طبقة قاعدة بيانات. هذا هو الحال لأنه يمكن التحقق من جميع الرموز المميزة لـ JWT من تلقاء نفسها ، ويمكن أن تحتوي أيضًا على وقت للعيش في قيم.

أيضًا ، يجب عليك دائمًا التأكد من أن جميع نقاط نهاية واجهة برمجة التطبيقات الخاصة بك لا يمكن الوصول إليها إلا من خلال اتصال آمن باستخدام HTTPS.

في مقالة سابقة ، أوضحنا أساليب مصادقة الويب بالتفصيل - أوصي بتفحصها!

# 7: استخدام الطلبات الشرطية

الطلبات الشرطية هي طلبات HTTP يتم تنفيذها بشكل مختلف اعتمادًا على رؤوس HTTP محددة. يمكنك التفكير في هذه الرؤوس كشروط مسبقة: إذا تم الوفاء بها ، فسيتم تنفيذ الطلبات بطريقة مختلفة.

تحاول هذه الرؤوس التحقق مما إذا كان إصدار المورد المخزن على الخادم يطابق إصدارًا معينًا من نفس المورد. بسبب هذا السبب ، يمكن أن تكون هذه الرؤوس:

  • الطابع الزمني للتعديل الأخير ،
  • أو علامة كيان ، والتي تختلف عن كل إصدار.

هذه الرؤوس هي:

  • التعديل الأخير (للإشارة إلى آخر مرة تم فيها تعديل المورد) ،
  • Etag (للإشارة إلى علامة الكيان) ،
  • If-Modified-Since (يستخدم مع رأس Last-Modified) ،
  • If-None-Match (يستخدم مع رأس Etag) ،

دعنا نلقي نظرة على مثال!

لم يكن لدى العميل أدناه أي إصدارات سابقة من مورد المستند ، لذلك لم يتم تطبيق العنوان If-Modified-Since ، أو رأس If-None-Match عند إرسال المورد. بعد ذلك ، يستجيب الخادم مع تعيين رؤوس Etag و Last-Modified بشكل صحيح.

من وثائق الطلب الشرطي MDN

يمكن للعميل تعيين رؤوس If-Modified-Since و If-None-Match بمجرد محاولة طلب نفس المورد - نظرًا لأنه يحتوي على إصدار الآن. إذا كانت الاستجابة هي نفسها ، فسيستجيب الخادم ببساطة بالحالة 304 - غير معدلة ولا يرسل المورد مرة أخرى.

من وثائق الطلب الشرطي MDN

# 8: احتضان معدل الحد

يتم استخدام تحديد السعر للتحكم في عدد الطلبات التي يمكن للمستهلك المعطى إرسالها إلى واجهة برمجة التطبيقات.

لإعلام مستخدمي API بعدد الطلبات التي تركوها ، عيّن الرؤوس التالية:

  • X-Rate-Limit-Limit ، عدد الطلبات المسموح بها في فاصل زمني معين
  • X- معدل الحد المتبقي ، عدد الطلبات المتبقية في نفس الفترة الزمنية ،
  • X-Rate-limit-Reset ، الوقت الذي سيتم فيه إعادة ضبط حد السعر.

معظم أطر عمل HTTP تدعمه خارج الصندوق (أو مع الإضافات). على سبيل المثال ، إذا كنت تستخدم Koa ، فهناك حزمة koa-ratelimit.

لاحظ أن نافذة الوقت يمكن أن تختلف بناءً على مزودي API المختلفين - على سبيل المثال ، يستخدم GitHub ساعة لذلك ، بينما يستخدم Twitter 15 دقيقة.

# 9: إنشاء وثائق API المناسبة

تكتب واجهات برمجة التطبيقات حتى يتمكن الآخرون من استخدامها والاستفادة منها. توفير وثائق API لواجهة برمجة التطبيقات (API) الخاصة بـ Node.js أمر بالغ الأهمية.

يمكن لمشاريع المصادر المفتوحة التالية مساعدتك في إنشاء وثائق لواجهة برمجة التطبيقات:

  • مخطط API
  • اختيال

بدلاً من ذلك ، إذا كنت ترغب في استخدام المنتجات المستضافة ، يمكنك الذهاب إلى Apiary.

# 10: لا تفوت مستقبل واجهات برمجة التطبيقات

في السنوات الماضية ، نشأت لغتان رئيسيتان للاستعلام عن واجهات برمجة التطبيقات - وهما GraphQL من Facebook و Falcor من Netflix. لكن لماذا نحتاج إليهم؟

تخيل طلب مورد RESTful التالي:

/ المنظمة / 1 / الفضاء / 2 / مستندات / 1 / المتعاونين؟
تشمل = بريدك & صفحة = 1 & الحد = 10

يمكن أن ينفد هذا الأمر بسهولة تامة - حيث ترغب في الحصول على نفس تنسيق الاستجابة لجميع طرزك طوال الوقت. هذا هو المكان الذي يمكن أن يساعدك فيه GraphQL و Falcor.

حول GraphQL

GraphQL هي لغة استعلام لواجهة برمجة التطبيقات ووقت تشغيل للوفاء بتلك الاستعلامات مع بياناتك الحالية. يوفر GraphQL وصفًا كاملاً ومفهومًا للبيانات الموجودة في واجهة برمجة التطبيقات ، ويمنح العملاء القدرة على طلب ما يحتاجون إليه تمامًا ولا شيء أكثر من ذلك ، ويسهل تطوير واجهات برمجة التطبيقات (API) بمرور الوقت ، ويمكّن أدوات مطوّري قوية. - اقرأ المزيد هنا.

حول فالكور

Falcor هي عبارة عن منصة بيانات مبتكرة تشغل واجهة مستخدم Netflix. يسمح لك Falcor بنمذجة جميع بياناتك الخلفية ككائن Virtual JSON واحد على خادم Node الخاص بك. على العميل ، فأنت تعمل مع كائن JSON البعيد الخاص بك باستخدام عمليات JavaScript مألوفة مثل get ، set ، call إذا كنت تعرف بياناتك ، فأنت تعرف واجهة برمجة التطبيقات. - اقرأ المزيد هنا.

واجهات برمجة التطبيقات REST مذهلة للإلهام

إذا كنت على وشك البدء في تطوير واجهة برمجة تطبيقات Node.js REST أو إنشاء إصدار جديد من إصدار أقدم ، فقد جمعنا أربعة أمثلة واقعية تستحق التدقيق:

  • واجهة برمجة تطبيقات جيثب
  • Twilio API
  • شريط API
  • واجهة برمجة تطبيقات DigitalOcean

آمل أن يكون لديك الآن فهم أفضل لكيفية كتابة واجهات برمجة التطبيقات باستخدام Node.js. واسمحوا لي أن أعرف في التعليقات إذا كنت تفوت أي شيء!

نُشر في الأصل على blog.risingstack.com في 21 فبراير 2017.