تحتاج معظم التطبيقات حاليًا إلى التواصل مع بعض الخوادم لجلب البيانات منها أو لإتمام بعض المهام، فمثلًا في تطبيق ويب لشراء الكتب سيحتاج للتواصل مع خادم إدارة طلبات الزبائن وخادم مستودع الكتب وخادم إتمام الدفع، حيث تتواصل تلك الخدمات مع بعضها عن طريق الويب عبر الواجهات البرمجية API وتتبادل البيانات برمجيًا.
توفر نود دعمًا للتواصل عن طريق طلبات HTTP مع واجهات API عبر الويب، فتتيح الوحدة البرمجية http والوحدة https، حيث تحتوي كل منهما على التوابع اللازمة لإنشاء خادم HTTP لمعالجة الطلبات الواردة إلى الخادم، وتوابع لإنشاء طلبات HTTP وإرسالها إلى الخوادم الأخرى، حيث تسمح هاتين الميزتين بتطوير تطبيقات ويب حديثة تعتمد على الواجهات البرمجية API للتواصل بينها، ولا حاجة لتثبيت أي وحدة برمجية خارجية حيث تأتي تلك الوحدات جاهزة مع نود افتراضيًا.
سنتعلم في هذا المقال كيف يمكننا الاستفادة من الوحدة https لإرسال طلبات HTTP بمثال عن التعامل مع خادم JSON Placeholder وهو واجهة برمجية API وهمية تستخدم في عمليات التدريب والاختبار، حيث سنتعلم طريقة إرسال طلب HTTP لطلب البيانات من نوع GET، ثم سنتعرف على طرق تخصيص الطلب المرسل كإضافة الترويسات، وسنتعرف أيضًا على الطلبات بمختلف أنواعها مثل POST و PUT و DELETE والتي تستخدم لتعديل البيانات على الخوادم الأخرى.
المستلزمات
- نسخة نود مثبتة على جهازك، حيث استخدمنا في هذا المقال الإصدار رقم 10.19.0.
- تعتمد توابع إرسال طلبات HTTP على واجهة مجرى البيانات stream في نود وهي بدورها نسخة من كائن مرسل الأحداث event emitter، لذا يمكن التعامل مع البيانات الواردة منها بنفس طريقة تعاملنا مع الأحداث المرسلة، وللتعرف على مرسل الأحداث وطريقة التعامل معه يمكنك مراجعة المقال التاسع من هذه السلسلة.
إرسال طلب من نوع GET
إن أردنا طلب بيانات من خادم ويب ما عبر واجهته البرمجية API نرسل إليه عادة طلب HTTP من نوع GET، ففي هذه الفقرة سنتعلم طريقة إرسال تلك الطلبات في نود وتحديدًا لجلب مصفوفة بيانات بصيغة JSON تحتوي على بيانات حسابات شخصية لمستخدمين وهميين من واجهة برمجية API متاحة للعموم، حيث تحوي الوحدة البرمجية https على تابعين يمكن استخدامهما لإرسال طلبات من نوع GET هما التابع get()، والتابع request() الذي يمكن استخدامه لإرسال طلبات من أنواع متعددة أخرى كما سنتعلم لاحقًا، ولنبدأ أولًا بالتعرف على التابع get().
إرسال الطلبات باستخدام التابع get()
صيغة استخدام التابع get() تكون كالتالي:
https.get(URL_String, Callback_Function) { Action }
حيث نمرر له سلسلة نصية كمعامل أول تحوي المسار الذي سنرسل الطلب إليه، والمعامل الثاني يكون دالة رد النداء callback function لمعالجة نتيجة الطلب.
سنبدأ بإنشاء مجلد جديد للمشروع سيحوي الأمثلة التي سنكتبها ضمن هذا الفصل كالتالي:
$ mkdir requests
وندخل إلى المجلد:
$ cd requests
ننشئ ملف جافاسكربت جديد ونفتحه باستخدام أي محرر نصوص حيث سنستخدم في أمثلتنا محرر نانو nano كالتالي:
$ nano getRequestWithGet.js
ونبدأ باستيراد الوحدة https كالتالي:
const https = require('https');
ملاحظة: يوجد في نود وحدتين برمجيتين هما http و https تحويان على نفس التوابع التي تعمل بنفس الطريقة، والفرق بينها أن التوابع ضمن https ترسل الطلبات عبر طبقة أمان النقل Transport Layer Security أو TLS/SSL، وسنرسل الطلبات في أمثلتنا عبر HTTPS لذا سنستخدم تلك التوابع من الوحدة https، بينما لو كنا سنرسل الطلبات عبر HTTP فيجب استخدام توابع الوحدة http بدلًا منها.
نبدأ بكتابة شيفرة إرسال طلب GET إلى الواجهة البرمجية API لجلب بيانات المستخدمين، حيث سنرسل طلبًا إلى واجهة JSON Placeholder وهي واجهة برمجية متاحة للاستخدام العام لأغراض الاختبار، ولا تتأثر البيانات على ذلك الخادم بالطلبات المرسلة فمهمته فقط محاكاة عمل خادم حقيقي، حيث سيرجع لنا دومًا بيانات وهمية طالما أن الطلب المرسل إليه سليم، لنبدأ بكتابة الشيفرة التالية:
const https = require('https'); let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => { });
كما ذكرنا سابقًا يقبل التابع get() معاملين وهما المسار الوجهة للطلب URL كسلسلة نصية للواجهة البرمجية، ودالة رد نداء لمعالجة نتيجة طلب HTTP الواردة، حيث يمكن استخراج البيانات من الرد ضمن دالة رد النداء.
يحمل طلب HTTP على رمز الحالة status code وهو عدد يشير إلى نجاح الطلب من عدمه، فمثلًا إذا كانت قيمة الرمز بين 200 و 299 فالطلب ناجح، أما إذا كان بين 400 و 599 فهناك خطأ ما، وفي مثالنا الرد من الواجهة البرمجية يجب أن يحتوي على رمز الحالة 200 إن نجح وهو أول ما سنتحقق منه ضمن تابع رد النداء لمعالجة الطلب كالتالي:
const https = require('https'); let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => { if (res.statusCode !== 200) { console.error(`Did not get an OK from the server. Code: ${res.statusCode}`); res.resume(); return; } });
يحوي كائن الرد res المُمرر لدالة رد النداء على الخاصية statusCode والتي تمثِّل قيمة رمز الحالة، وإذا لم تكن قيمته تساوي 200 سنطبع رسالة خطأ إلى الطرفية ونخرج مباشرةً.
نلاحظ استدعاء التابع res.resume() من كائن الرد وهي طريقة لتحسين أداء البرنامج فعند إرسال طلبات HTTP في نود يتم عادة معالجة البيانات المرسلة ضمن الطلب كاملةً، أما عند استدعائنا للتابع res.resume() فإننا نخبر نود بتجاهل البيانات ضمن مجرى كائن الرد، وهي طريقة أسرع من لو تُركت تلك البيانات لالتقاطها في مرحلة كنس المهملات garbage collection التي تتم دوريًا لتفريغ الذاكرة المستخدمة من قبل التطبيق.
والآن بعد أن تحققنا من رمز الحالة للرد سنبدأ بقراءة البيانات الواردة حيث تتوفر البيانات ضمن كائن مجرى الرد على دفعات، ويمكننا قراءتها بالاستماع إلى الحدث data من كائن الرد ثم تجميعها معًا ثم تحليلها بصيغة JSON لنتمكن من استخدامها ضمن التطبيق، لذلك سنضيف الشيفرة التالية ضمن تابع رد النداء:
const https = require('https'); let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => { if (res.statusCode !== 200) { console.error(`Did not get an OK from the server. Code: ${res.statusCode}`); res.resume(); return; } let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('close', () => { console.log('Retrieved all data'); console.log(JSON.parse(data)); }); });
عرفنا متغيرًا جديدًا بالاسم data والذي يحتوي على سلسلة نصية فارغة، حيث يمكننا تجميع البيانات الواردة إما على شكل مصفوفة من الأعداد تمثل البيانات للبايتات المكونة لها، أو على شكل سلسلة نصية وهو ما سنستخدمه في مثالنا لسهولة تحويل السلسلة النصية الناتجة عن عملية التجميع إلى كائن جافاسكربت.
نضيف بعد ذلك تابع الاستماع للبيانات الواردة على دفعات من الحدث data ونجمع البيانات كلها ضمن المتغير السابق data، ويمكننا التأكد من انتهاء دفعات البيانات الواردة عند إطلاق حدث الإغلاق close من كائن الرد، وبعدها يمكننا تحويل السلسلة النصية بصيغة JSON ضمن المتغير data وطباعة القيمة النهائية إلى الطرفية، وبذلك نكون قد أكملنا كتابة عملية إرسال طلب إلى واجهة برمجية ستُرسل بدورها مصفوفة من بيانات حسابات شخصية لثلاثة مستخدمين بصيغة JSON ونقرأ الرد الوارد.
بقي لدينا إضافة معالجة لحالة رمي خطأ في حال لم نتمكن من إرسال الطلب لسبب ما، كحالة عدم وجود اتصال بالإنترنت كالتالي:
... res.on('data', (chunk) => { data += chunk; }); res.on('close', () => { console.log('Retrieved all data'); console.log(JSON.parse(data)); }); }); request.on('error', (err) => { console.error(`Encountered an error trying to make a request: ${err.message}`); });
عند حدوث خطأ في عملية الإرسال سنتلقى الحدث error من كائن الطلب، وإذا لم نستمع لهذا الحدث فسيرمى الخطأ الناتج ما يؤدي لإيقاف عمل البرنامج، لذلك نضيف دالة استماع للحدث error على كائن الطلب باستخدام التابع on() والذي سيطبع رسالة الخطأ الوارد إلى الطرفية، وبذلك نكون قد انتهينا من كتابة البرنامج.
والآن نحفظ الملف ونخرج منه وننفذه باستخدام الأمر node كالتالي:
$ node getRequestWithGet.js
نحصل على الخرج التالي الذي يمثل الرد الوارد على الطلب المُرسل:
Retrieved all data
[
{
id: 1,
name: 'Leanne Graham',
username: 'Bret',
email: 'Sincere@april.biz',
address: {
street: 'Kulas Light',
suite: 'Apt. 556',
city: 'Gwenborough',
zipcode: '92998-3874',
geo: [Object]
},
phone: '1-770-736-8031 x56442',
website: 'hildegard.org',
company: {
name: 'Romaguera-Crona',
catchPhrase: 'Multi-layered client-server neural-net',
bs: 'harness real-time e-markets'
}
},
{
id: 2,
name: 'Ervin Howell',
username: 'Antonette',
email: 'Shanna@melissa.tv',
address: {
street: 'Victor Plains',
suite: 'Suite 879',
city: 'Wisokyburgh',
zipcode: '90566-7771',
geo: [Object]
},
phone: '010-692-6593 x09125',
website: 'anastasia.net',
company: {
name: 'Deckow-Crist',
catchPhrase: 'Proactive didactic contingency',
bs: 'synergize scalable supply-chains'
}
}
]
بذلك نكون قد أرسلنا طلبًا من نوع GET بنجاح باستخدام مكتبات نود فقط، حيث أن التابع الذي استخدمناه get() يوجد في نود بسبب كثرة الحاجة لإرسال الطلبات من نوع GET، بينما الطريقة الأساسية لإرسال الطلبات هي باستخدام التابع request() والذي يمكنه إرسال أي نوع من الطلبات، وهو ما سنتعرف عليه في القسم التالي حيث سنستخدمه لإرسال طلب من نوع GET.
إرسال الطلبات باستخدام التابع request()
يمكن استخدام التابع request() بعدة صيغ والصيغة التي سنستخدمها في أمثلتنا هي كالتالي:
https.request(URL_String, Options_Object, Callback_Function) { Action }
حيث نمرر له سلسلة نصية كمعامل أول تحتوي على مسار الواجهة البرمجية API الذي سنرسل الطلب إليه، والمعامل الثاني هو كائن جافاسكربت يحتوي على عدة خيارات للطلب المرسل، والمعامل الأخير المُمرر هو دالة رد النداء callback لمعالجة نتيجة الطلب.
نبدأ بإنشاء ملف جافاسكربت جديد بالاسم getRequestWithRequest.js:
$ nano getRequestWithRequest.js
سنكتب برنامجًا مشابهًا لما كتبناه في القسم السابق ضمن الملف getRequestWithGet.js، حيث نبدأ باستيراد الوحدة https كالتالي:
const https = require('https');
ثم نعرف كائن جافاسكربت يحتوي على الخاصية method كالتالي:
const https = require('https'); const options = { method: 'GET' };
تعبر الخاصية method ضمن كائن خيارات التابع request() عن نوع الطلب الذي نريد إرساله، والآن نُرسل الطلب كما فعلنا سابقًا لكن مع بعض الاختلافات كالتالي:
... let request = https.request('https://jsonplaceholder.typicode.com/users?_limit=2', options, (res) => { if (res.statusCode !== 200) { console.error(`Did not get an OK from the server. Code: ${res.statusCode}`); res.resume(); return; } let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('close', () => { console.log('Retrieved all data'); console.log(JSON.parse(data)); }); }); request.end(); request.on('error', (err) => { console.error(`Encountered an error trying to make a request: ${err.message}`); });
مررنا مسار الوجهة للطلب كمعامل أول للتابع request() ثم كائن خيارات HTTP كمعامل ثاني، وبعدها دالة رد النداء لمعالجة الرد، حيث حددنا نوع الطلب المرسل كطلب GET ضمن كائن الخيارات options الذي عرفناه سابقًا، وبقي دالة رد النداء لمعالجة الطلب كما هو في المثال السابق، وأضفنا استدعاءً للتابع end() من كائن الطلب request، حيث يجب استدعاء هذا التابع عند إرسال الطلبات باستخدام request() لإتمام الطلب وإرساله، وفي حال لم نستدعيه فلن يُرسل الطلب ويبقى نود ينتظر منا إضافة بيانات جديدة إلى الطلب.
والآن نحفظ الملف ونخرج منه ثم ننفذ البرنامج:
$ node getRequestWithRequest.js
ليظهر الخرج التالي كما المثال السابق تمامًا:
Retrieved all data
[
{
id: 1,
name: 'Leanne Graham',
username: 'Bret',
email: 'Sincere@april.biz',
address: {
street: 'Kulas Light',
suite: 'Apt. 556',
city: 'Gwenborough',
zipcode: '92998-3874',
geo: [Object]
},
phone: '1-770-736-8031 x56442',
website: 'hildegard.org',
company: {
name: 'Romaguera-Crona',
catchPhrase: 'Multi-layered client-server neural-net',
bs: 'harness real-time e-markets'
}
},
{
id: 2,
name: 'Ervin Howell',
username: 'Antonette',
email: 'Shanna@melissa.tv',
address: {
street: 'Victor Plains',
suite: 'Suite 879',
city: 'Wisokyburgh',
zipcode: '90566-7771',
geo: [Object]
},
phone: '010-692-6593 x09125',
website: 'anastasia.net',
company: {
name: 'Deckow-Crist',
catchPhrase: 'Proactive didactic contingency',
bs: 'synergize scalable supply-chains'
}
}
]
وبذلك نكون قد تعرفنا على طريقة استخدام التابع request() لإرسال الطلبات من نوع GET وهو تابع أقوى من التابع السابق get() حيث يسمح بتخصيصات عدة على الطلب المرسل كتحديد نوعه وخيارات أخرى سنتعرف عليها في الفقرة التالية.
تخصيص خيارات HTTP للتابع request()
يمكن استخدام التابع request() لإرسال طلبات HTTP دون تمرير عنوان مسار الوجهة للطلب كمعامل أول بل بتمريره ضمن كائن الخيارات options لتصبح صيغة استدعاء التابع كالتالي:
https.request(Options_Object, Callback_Function) { Action }
في هذه الفقرة سنستخدم هذه الصيغة للتركيز على إعداد وتخصيص خيارات التابع request()، لذا نعود إلى ملف المثال السابق getRequestWithRequest.js ونعدله بأن نزيل المسار URL المُمرر للتابع request() لتصبح المعاملات المُمررة له هي كائن الخيارات options ودالة رد النداء فقط كالتالي:
const https = require('https'); const options = { method: 'GET', }; let request = https.request(options, (res) => { ...
لنضيف الخيارات الجديدة إلى الكائن options كالتالي:
const https = require('https'); const options = { host: 'jsonplaceholder.typicode.com', path: '/users?_limit=2', method: 'GET' }; let request = https.request(options, (res) => { ...
نلاحظ أنه وبدلًا من تمرير المسار كاملًا فإننا نمرره على قسمين ضمن الخاصيتين host و path حيث تُعبّر الخاصية host عن عنوان النطاق أو عنوان IP للخادم الوجهة، أما الخاصية path فهي كل ما يلي بعد ذلك ضمن المسار بما فيها معاملات الاستعلام query parameters التي تأتي بعد إشارة الاستفهام.
ويمكن أن تحتوي الخيارات على بيانات مفيدة أخرى للطلب المرسل مثل الترويسات المرسلة وهي بيانات وصفية عن الطلب نفسه، فمثلًا عادة تتطلب الواجهة البرمجية API تحديد صيغة البيانات المرسلة من عدة صيغ مدعومة مثل JSON أو CSV أو XML، ولتحديد الصيغة التي يطلبها المستخدم يمكن للواجهة البرمجية معاينة قيمة الترويسة Accept ضمن الطلب الوارد إليها وتحدد على أساسه الصيغة المناسبة لإرسالها.
تُعبّر الترويسة Accept عن نوع البيانات التي يمكن للمستخدم التعامل معها، وبما أننا نتعامل مع واجهة برمجية تدعم صيغة JSON فقط، فيمكننا إضافة الترويسة Accept وإضافة قيمة لها توضح أننا نريد البيانات بصيغة JSON كالتالي:
const https = require('https'); const options = { host: 'jsonplaceholder.typicode.com', path: '/users?_limit=2', method: 'GET', headers: { 'Accept': 'application/json' } };
وبذلك نكون قد تعرفنا على أكثر أربعة خيارات استخدامًا ضمن طلبات HTTP وهي عنوان المضيف host و المسار path ونوع الطلب method والترويسات headers، ويوجد العديد من الخيارات الأخرى المدعومة يمكنك الرجوع إلى التوثيق الرسمي لها ضمن نود للتعرف عليها.
والآن نحفظ الملف ونخرج منه ثم ننفذ البرنامج لنختبر طريقة إرسال الطلبات بتمرير كائن الخيارات فقط:
$ node getRequestWithRequest.js
ليظهر لنا بيانات الرد مطابقة للأمثلة السابقة:
Retrieved all data [ { id: 1, name: 'Leanne Graham', username: 'Bret', email: 'Sincere@april.biz', address: { street: 'Kulas Light', suite: 'Apt. 556', city: 'Gwenborough', zipcode: '92998-3874', geo: [Object] }, phone: '1-770-736-8031 x56442', website: 'hildegard.org', company: { name: 'Romaguera-Crona', catchPhrase: 'Multi-layered client-server neural-net', bs: 'harness real-time e-markets' } }, { id: 2, name: 'Ervin Howell', username: 'Antonette', email: 'Shanna@melissa.tv', address: { street: 'Victor Plains', suite: 'Suite 879', city: 'Wisokyburgh', zipcode: '90566-7771', geo: [Object] }, phone: '010-692-6593 x09125', website: 'anastasia.net', company: { name: 'Deckow-Crist', catchPhrase: 'Proactive didactic contingency', bs: 'synergize scalable supply-chains' } } ]
تختلف متطلبات الواجهات البرمجية API بحسب الجهة المطورة لها، لذا من الضروري التعامل مع كائن الخيارات options لتخصيص الطلب بحسب حاجة التطبيق والخادم، من تحديد نوع البيانات المطلوبة وإضافة الترويسات المناسبة وبعض التخصيصات الأخرى.
أرسلنا ضمن كل الأمثلة السابقة طلبات فقط من نوع GET لجلب البيانات، وفي الفقرة التالية سنتعلم طريقة إرسال الطلبات من نوع POST والتي تستخدم لرفع البيانات إلى الخادم.
إرسال طلب من نوع POST
نستخدم الطلبات من نوع POST لرفع البيانات إلى الخادم أو لطلب إنشاء بيانات جديدة من قبل الخادم، وفي هذه الفقرة سنتعرف على طريقة إرسال مثل هذه الطلبات في نود عبر إرسال طلب إنشاء مستخدم جديد إلى المسار users على الواجهة البرمجية API.
يمكننا إعادة استخدام بعض الشيفرات من مثال إرسال طلب من نوع GET السابق لإرسال طلبات من نوع POST مع إجراء بعض التعديلات عليها:
-
تعديل نوع الطلب ضمن كائن الخيارات
optionsليصبحPOST. - تعيين ترويسة نوع المحتوى المُرسل وهو في حالتنا بصيغة JSON.
- التأكد من رمز الحالة للرد لتأكيد نجاح إنشاء مستخدم جديد.
- رفع بيانات المستخدم الجديد.
نبدأ بإنشاء ملف جافاسكربت جديد بالاسم postRequest.js ونفتحه ضمن محرر النصوص:
$ nano postRequest.js
ونبدأ كما سابقًا باستيراد الوحدة https وتعريف كائن الخيارات options كالتالي:
const https = require('https'); const options = { host: 'jsonplaceholder.typicode.com', path: '/users', method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json; charset=UTF-8' } };
ونعدل خيار مسار الطلب path ليتوافق مع مسار إرسال الطلبات من نوع POST على الخادم، ونعدل خيار نوع الطلب المرسل method إلى القيمة POST، وأخيرًا نضيف الترويسة Content-Type ضمن الخيارات والتي تدل الخادم على نوع البيانات التي أرسلناها مع الطلب وهي في حالتنا بصيغة JSON وبترميز من نوع UTF-8، ثم نُرسل الطلب باستدعاء التابع request() كما فعلنا تمامًا عند إرسال طلب من نوع GET سابقًا ولكن هذه المرة سنتحقق من رمز الحالة للرد بقيمة تختلف عن 200 كالتالي:
... const request = https.request(options, (res) => { if (res.statusCode !== 201) { console.error(`Did not get a Created from the server. Code: ${res.statusCode}`); res.resume(); return; } let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('close', () => { console.log('Added new user'); console.log(JSON.parse(data)); }); });
تحققنا من صحة العملية بالتحقق من قيمة رمز الحالة بأن يساوي 201، وهو الرمز الذي يدل على إنشاء مورد جديد على الخادم بنجاح، ويُعبّر الطلب المرسل عن إنشاء مستخدم جديد لهذا سنحتاج لرفع بيانات هذا المستخدم وإرفاقها ضمن الطلب، لذا سننشئ تلك البيانات كالتالي:
... const requestData = { name: 'New User', username: 'hsoub', email: 'user@hsoub.com', address: { street: 'North Pole', city: 'Murmansk', zipcode: '12345-6789', }, phone: '555-1212', website: 'hsoub.com', company: { name: 'Hsoub', catchPhrase: 'Welcome to hsoub academy', bs: 'cloud scale security' } }; request.write(JSON.stringify(requestData));
عرفنا بيانات المستخدم الجديد ضمن المتغير requestData على شكل كائن جافاسكربت يحتوي على بيانات المستخدم، ونلاحظ أننا لم نرفق قيمة المعرف id للمستخدم حيث أن هذه القيمة يولدها الخادم تلقائيًا للبيانات الجديدة، ثم استدعينا التابع request.write() والذي يقبل سلسلة نصية أو كائن مخزن مؤقت buffer ليتم إرسالها ضمن الطلب، وبما أن البيانات لدينا ضمن المتغير requestData هي كائن جافاسكربت فيجب تحويله إلى سلسلة نصية باستخدام JSON.stringify.
ولإنهاء عملية الإرسال ننهي الطلب عبر استدعاء request.end() ونتحقق من حدوث أي أخطاء في عملية الإرسال كالتالي:
... request.end(); request.on('error', (err) => { console.error(`Encountered an error trying to make a request: ${err.message}`); });
من الضروري استدعاء التابع end() لإنهاء الطلب وللإشارة إلى نود بأن كل البيانات التي نريد إرسالها ضمن الطلب قد أرفقت وأصبح بالإمكان إرساله.
والآن نحفظ الملف ونخرج منه ثم ننفذ البرنامج ونتأكد من عملية إنشاء المستخدم الجديد:
$ node postRequest.js
سنحصل على الخرج التالي:
Added new user
{
name: 'New User',
username: 'hsoub',
email: 'user@hsoub.com',
address: { street: 'North Pole', city: 'Murmansk', zipcode: '12345-6789' },
phone: '555-1212',
website: 'hsoub.com',
company: {
name: 'Hsoub',
catchPhrase: 'Welcome to the hsoub academy',
bs: 'cloud scale security'
},
id: 11
}
ما يعني أن الطلب تم بنجاح، حيث أعاد الخادم بيانات المستخدم التي أرسلناها مضافًا إليها قيمة معرّف المستخدم ID التي تم توليدها له، وبذلك نكون قد تعلمنا طريقة إرسال الطلبات من نوع POST لرفع البيانات إلى الخادم باستخدام نود، وفي الفقرة التالية سنتعلم طريقة إرسال الطلبات من نوع PUT للتعديل على بيانات موجودة مسبقًا.
إرسال طلب من نوع PUT
تُستخدم الطلبات من نوع PUT لرفع البيانات إلى الخادم بشكل مشابه للطلبات من نوع POST، ولكن الفرق أنه عند تنفيذ طلب من نوع PUT عدة مرات سنحصل على نفس النتيجة، بينما عند تكرار نفس طلب POST عدة مرات سنضيف بذلك البيانات المرسلة أكثر من مرة إلى الخادم، وطريقة إرسال هذا الطلب مشابهة للطلب من نوع POST حيث نعرف الخيارات ونُنشئ الطلب ونكتب البيانات التي نريد رفعها إلى الطلب ثم نتحقق من الرد الوارد في نتيجة الطلب.
نختبر ذلك بإنشاء طلب من نوع PUT لتعديل اسم المستخدم لأول مستخدم، وبما أن طريقة إرسال الطلب مشابهة لطريقة إرسال الطلب من نوع POST يمكننا الاستفادة من المثال السابق ونسخ الملف postRequest.js إلى ملف جديد بالاسم putRequest.js كالتالي:
$ cp postRequest.js putRequest.js
نفتح الملف putRequest.js ضمن محرر النصوص:
$ nano putRequest.js
ونعدل نوع الطلب إلى PUT ومساره إلى https://jsonplaceholder.typicode.com/users/1 والبيانات المرسلة كالتالي:
const https = require('https'); const options = { host: 'jsonplaceholder.typicode.com', path: '/users/1', method: 'PUT', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json; charset=UTF-8' } }; const request = https.request(options, (res) => { if (res.statusCode !== 200) { console.error(`Did not get an OK from the server. Code: ${res.statusCode}`); res.resume(); return; } let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('close', () => { console.log('Updated data'); console.log(JSON.parse(data)); }); }); const requestData = { username: 'hsoub' }; request.write(JSON.stringify(requestData)); request.end(); request.on('error', (err) => { console.error(`Encountered an error trying to make a request: ${err.message}`); });
نلاحظ تعديل قيم المسار path ونوع الطلب method ضمن كائن الخصائص options حيث يحوي المسار على معرّف المستخدم الذي نود تعديل بياناته، ثم نتحقق من من رمز الحالة للطلب بأن يكون بالقيمة 200 ما يدل على نجاح الطلب، ونلاحظ أن البيانات التي أرسلناها تحوي فقط على الخصائص التي نريد تحديثها من بيانات المستخدم.
والآن نحفظ الملف ونخرج منه ثم ننفذ البرنامج:
$ node putRequest.js
ليظهر الخرج التالي:
Updated data
{ username: 'hsoub', id: 1 }
أرسلنا بنجاح طلب من نوع PUT لتعديل بيانات مستخدم موجودة مسبقًا على الخادم، وبذلك نكون قد تعلمنا طرق طلب البيانات ورفعها وتحديثها، وسنتعلم في الفقرة التالية كيف يمكن حذف البيانات من الخادم بإرسال طلب من النوع DELETE.
إرسال طلب من نوع DELETE
تستخدم الطلبات من نوع DELETE لحذف البيانات من الخادم، ويمكن أن يحتوي الطلب على بيانات مرفقة ضمنه ولكن معظم الواجهات البرمجية API لا تتطلب ذلك، حيث يستخدم هذا النوع من الطلبات لحذف بيانات كائن ما كليًا من الخادم.
سنرسل في هذه الفقرة طلب من هذا النوع لحذف بيانات أحد المستخدمين، وطريقة إرسال هذا الطلب مشابهة لطريقة إرسال طلب من نوع GET، لذا يمكننا نسخ ملف المثال السابق getRequestWithRequest.js إلى ملف جديد بالاسم deleteRequest.js كالتالي:
$ cp getRequestWithRequest.js deleteRequest.js
ونفتح الملف الجديد ضمن محرر النصوص:
$ nano deleteRequest.js
ونعدل الشيفرة لإرسال طلب حذف لأول مستخدم كالتالي:
const https = require('https'); const options = { host: 'jsonplaceholder.typicode.com', path: '/users/1', method: 'DELETE', headers: { 'Accept': 'application/json', } }; const request = https.request(options, (res) => { if (res.statusCode !== 200) { console.error(`Did not get an OK from the server. Code: ${res.statusCode}`); res.resume(); return; } let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('close', () => { console.log('Deleted user'); console.log(JSON.parse(data)); }); }); request.end(); request.on('error', (err) => { console.error(`Encountered an error trying to make a request: ${err.message}`); });
عدلنا قيمة المسار path ضمن كائن خيارات الطلب ليحوي معرّف المستخدم الذي نريد حذفه، وعدلنا نوع الطلب إلى DELETE، والآن نحفظ الملف ونخرج منه ثم ننفذ البرنامج كالتالي:
$ node deleteRequest.js
لنحصل على الخرج:
Deleted user
{}
لا تعيد الواجهة البرمجية أي بيانات ضمن جسم الرد الوارد، ولكن رمز الحالة لهذا الرد يكون 200 أي تم حذف بيانات المستخدم بنجاح، وبذلك نكون قد تعرفنا على طريقة إرسال طلبات من نوع DELETE أيضًا في نود.
خاتمة
تعرفنا في هذا الفصل على طريقة إرسال الطلبات في نود بأنواعها مختلفة مثل GET و POST و PUT و DELETE دون استخدام أي مكتبات خارجية وفقط باستخدام الوحدة البرمجية https التي يوفرها نود، وتعرفنا على طريقة خاصة لإرسال الطلبات من نوع GET باستخدام التابع get() وكيف أن باقي الطلبات يمكن إرسالها باستخدام التابع request()، وتعاملنا ضمن الأمثلة مع واجهة برمجية API عامة ويمكن بنفس الطريقة إرسال الطلبات إلى مختلف أنواع الواجهات البرمجية.
ترجمة -وبتصرف- للمقال How To Create an HTTP Client with Core HTTP in Node.js.

أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.