كيفية الجمع بين المكالمات API REST مع وعود JavaScript في node.js أو OpenWhisk

سيناريو مألوف لمطوري node.js: تريد تقديم طلب HTTP إلى واجهة برمجة تطبيقات REST ، واعتمادًا على استجابة الطلب الأول ، تحتاج إلى تقديم المزيد من الطلبات.

لقد صادفت سيناريو مثل هذا في اليوم الآخر عندما قرأت منشور مدونة ستيفن أو جرادي عن حالة ترخيص المصدر المفتوح.

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

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

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

مع استكشافي لـ OpenWhisk ، أردت أن أرى ما إذا كانت هناك طريقة أكثر أناقة لحل هذه المشكلة. وهناك: مكتبة الوعد بالطلب (تباين لمكتبة عميل HTTP للطلب الشعبي لـ node.js).

الشروع في العمل مع طلب الوعد

للبدء: لاحظ أن طلب الوعد يتطلب تطبيق وعد Bluebird ومكتبة الطلب الأصلية. إذا لم يكن لديك بالفعل ، فقم بالتثبيت باستخدام npm.

npm تثبيت طلب طلب وعد

مع تثبيت التبعيات ، يمكنك تقديم طلبك الأول.

كل هذا يعمل على إعداد طلب GET إلى واجهة برمجة تطبيقات GitHub ، دون أي إذن ، ومعالجة قليلة جدًا للاستجابة. الشيء المثير هنا هو إذن ، والذي يعد الواجهة الرئيسية لواجهة برمجة تطبيقات Promises.

بعد ذلك ، أضف التعليمات البرمجية بحيث يكون لديك وقت أسهل في تشغيل الشفرة واختبارها. (يجب أيضًا الانتقال إلى إعدادات مستخدم GitHub والحصول على رمز وصول شخصي).

ما يحدث هنا هو أننا نعرّف كائن github الذي يعمل كحامل لرمزنا المميز. يتم تمرير الرمز المميز كوسيطة سطر أوامر إلى الرئيسي ، حيث سيكون معظم الإجراء. ستلاحظ أيضًا وظيفة getUser المضافة ، والتي تستخدم التفويض للحصول على ملف تعريف المستخدم للمستخدم الذي تم تسجيل دخوله حاليًا ككائن JSON. يمكنك استدعاء هذا للاختبار من سطر الأوامر مثل هذا:

عقدة $ Authenticated-request.js 
{
  "تسجيل الدخول": "trieloff" ،
  "معرف": 39613 ،
  "avatar_url": "https://avatars0.githubusercontent.com/u/39613؟v=3" ،
  "gravatar_id": "" ،
  "url": "https://api.github.com/users/trieloff" ،
  "html_url": "https://github.com/trieloff" ،
  "repos_url": "https://api.github.com/users/trieloff/repos"
...

في هذه المرحلة ، كل ما نفعله بالنتيجة هو تسجيل الدخول. لقد بدأنا للتو.

معالجة السلاسل مع الوعود

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

لتسلسل الطلبات ، نقوم بتعريف getUserReposUrl دالة جديدة ، والتي تستخدم مفتاح repos_url في كائن JSON الذي تم تمريره.

في الخطوة التالية ، نسحب قائمة المستودعات الفعلية من خلال تقديم طلب HTTP ثانٍ. لجعل الأمور أكثر فائدة للمطورين الذين لديهم الكثير من المستودعات على GitHub ، تستخدم واجهة برمجة تطبيقات GitHub ترقيم الصفحات. هذا يتيح لنا تجربة النموذج التالي على الفور:

طلب العودية تسلسل مع وعود

لا يعني تسلسل الطلب المتكرر أي شيء أكثر من ذلك نسميه دالة تقدم طلبًا ، والتي قد تطلق على نفسها لتقديم طلب آخر ، وما إلى ذلك. كل ما يتم إرجاعه هو إما وعود أو بيانات ، بمجرد الوفاء بالوعد وتقديم الطلب.

تبدو وظيفة getUserRepos التي نسميها التالية مألوفة نسبيًا ، ولكن في السطر 13 ، يبدأ التعامل مع استجابة أكثر تعقيدًا بعض الشيء. أول شيء يفعله هو التحقق مما إذا كانت قائمة repos المستردة قد تم تمريرها إليها ، وإذا لم يكن كذلك ، فستقوم بتهيئة تلك القائمة.

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

هذه المرة ، يتم تمرير repos ، وسيتم بناؤها مع التكرارات اللاحقة. نتيجة لذلك ، انتهى بنا المطاف بقائمة كاملة من المستودعات للمستخدم الحالي. بعد ذلك ، نحسن تلك القائمة.

رسم الخرائط وتصفية الردود مع الوعود

الآن وبعد أن تم إرجاع القائمة الكاملة ، يمكننا تشغيل الخريطة والتصفية على مجموعة المستودعات التي تم إرجاعها. ستؤدي مكالمات المرشح هذه إلى التخلص من جميع المستودعات الخاصة (أنا فقط أهتم بترخيص هذه المستودعات) والمستودعات المتشعبة (ليس مكاني لتعيين ترخيص لهم).

ستقوم الخريطة باستدعاء رخصة وظيفة لكل مستودع متبقي وإرجاع URI لملف الترخيص ، في حالة وجوده.

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

إثارة الطلبات بالوعود

في هذه الخطوة (شبه النهائية) ، نستبدل عنوان URL الذي تم إرجاعه بمزيد من المعلومات المفيدة: ما إذا كان طلب الحصول على عنوان URL هذا ينتج عنه خطأ أم لا.

تمامًا مثلما استخدمنا الخريطة من قبل لتحويل البيانات ، فسنقوم بذلك مرة أخرى ، فيما عدا في هذه الحالة ، فإن checkLicense للوظيفة تنفذ طلبًا وتعيد وعدًا.

الجانب الوحيد البسيط المعاكس حول checkLicense هو أنه يقوم بإرجاع خطأ عند نجاح الطلب. نظرًا لأن هدفنا هو العثور على مستودعات ليس لها ترخيص (حيث سيؤدي الطلب إلى رمز الحالة 404) ، فإن وظيفة معالجة الوعد المرفوض تكون أكثر إثارة للاهتمام قليلاً. تقوم بإرجاع عنوان URL لملف الترخيص المفقود.

التنظيف النهائي

في الخطوات النهائية ، نقوم بتصفية (باستخدام isMissing) جميع المستودعات التي لديها ترخيص خارج وتعيين (باستخدام createLicenseLink) عنوان URL لواجهة برمجة التطبيقات للترخيص مع رابط مناسب لواجهة ويب GitHub التي تسمح لك باختيار ترخيص لمستودع التخزين.

إجمالًا ، لم يستغرق الأمر أكثر من 100 سطر من التعليمات البرمجية للحصول على قائمة كاملة بالمستودعات العامة التي تفتقد إلى ترخيص. لم يقتض الأمر وقتًا طويلاً نسبيًا لتطوير هذا الرمز (بالكاد أكثر من التدقيق يدويًا) ، بل قمنا أيضًا (دون ملاحظة) بإنشاء وظيفة بدون خادم جاهزة للعمل على OpenWhisk.

إليك ما تم إرجاعه لحساب GitHub الخاص بي:

العقدة get-repos.js a4abc39daefa2a26b10cdefabcdefa5bac6defab
30 repos حتى الآن
هناك أكثر.
37 repos حتى الآن
['https://github.com/trieloff/creative-lights/new/master؟filename=LICENSE' ،
  "https://github.com/trieloff/excelsior/new/master؟filename=LICENSE،
  "https://github.com/trieloff/katacoda-scenarios/new/master؟filename=LICENSE،
  "https://github.com/trieloff/medium-feedreader/new/master؟filename=LICENSE،
  "https://github.com/trieloff/medium-tools/new/master؟filename=LICENSE،
  "https://github.com/trieloff/openlike/new/master؟filename=LICENSE،
  "https://github.com/trieloff/openwhisk-cljs/new/master؟filename=LICENSE،
  "https://github.com/trieloff/stackoverflow-bigqueries/new/master؟filename=LICENSE ']

بحلول الوقت الذي تقرأ فيه هذا ، يجب أن تحتوي جميع المستودعات أعلاه على ملفات LICENSE المفقودة.

جرب الكود على حسابك الخاص!