بناء واجهة برمجة تطبيقات Node.js Express لتحويل Markdown إلى HTML
نشرت: 2022-03-10Markdown هي لغة ترميز نصية خفيفة الوزن تسمح بتحويل النص المحدد إلى تنسيقات مختلفة. كان الهدف الأصلي من إنشاء Markdown هو تمكين الأشخاص "من الكتابة باستخدام تنسيق نص عادي سهل القراءة والكتابة" وتحويله اختياريًا إلى XHTML (أو HTML) صالح هيكليًا. حاليًا ، مع دعم WordPress Markdown ، أصبح التنسيق مستخدمًا على نطاق واسع.
الغرض من كتابة المقالة هو توضيح كيفية استخدام Node.js وإطار عمل Express لإنشاء نقطة نهاية API. السياق الذي سنتعلم فيه هذا هو من خلال بناء تطبيق يحول صيغة Markdown إلى HTML. سنضيف أيضًا آلية مصادقة إلى واجهة برمجة التطبيقات (API) لمنع إساءة استخدام تطبيقنا.
تطبيق Markdown Node.js
سيمكننا تطبيقنا الصغير للغاية ، والذي سنسميه "Markdown Converter" ، من نشر نص على غرار Markdown واسترداد إصدار HTML. سيتم إنشاء التطبيق باستخدام إطار عمل Node.js Express ، ودعم المصادقة لطلبات التحويل.
سنقوم ببناء التطبيق على مراحل صغيرة - في البداية نقوم بإنشاء سقالة باستخدام Express ثم إضافة ميزات مختلفة مثل المصادقة بينما نمضي قدمًا. لذلك دعونا نبدأ بالمرحلة الأولى لبناء التطبيق عن طريق إنشاء سقالة.
المرحلة 1: تثبيت Express
بافتراض أنك قمت بالفعل بتثبيت Node.js على نظامك ، قم بإنشاء دليل للاحتفاظ بتطبيقك (دعنا نسميه " markdown-api
") ، وانتقل إلى هذا الدليل:
$ mkdir markdown-api $ cd markdown-api
استخدم الأمر npm init لإنشاء ملف package.json لتطبيقك. يطالبك هذا الأمر بعدد من الأشياء مثل اسم وإصدار التطبيق الخاص بك.
في الوقت الحالي ، ما عليك سوى الضغط على Enter لقبول الإعدادات الافتراضية لمعظمها. لقد استخدمت ملف نقطة الإدخال الافتراضي كملف index.js ، ولكن يمكنك تجربة app.js أو غيره حسب تفضيلاتك.
الآن قم بتثبيت Express في دليل markdown-api
واحفظه في قائمة التبعيات:
$ npm install express --save
أنشئ ملف index.js في الدليل الحالي ( markdown-api
) وأضف الكود التالي لاختبار ما إذا كان Express framework مثبتًا بشكل صحيح:
Const express = require('express'); var app = express(); app.get('/', function(req, res){ res.send('Hello World!'); }); app.listen(3000);
استعرض الآن عنوان URL https://localhost:3000
للتحقق مما إذا كان ملف الاختبار يعمل بشكل صحيح. إذا كان كل شيء على ما يرام ، فسنرى Hello World! تحية في المتصفح ويمكننا المضي قدمًا في إنشاء واجهة برمجة تطبيقات أساسية لتحويل Markdown إلى HTML.
المرحلة 2: بناء قاعدة API
سيكون الغرض الأساسي من واجهة برمجة التطبيقات الخاصة بنا هو تحويل النص في صيغة Markdown إلى HTML. سيكون لواجهة برمجة التطبيقات نقطتا نهاية:
-
/login
-
/convert
ستسمح نقطة نهاية login
للتطبيق بمصادقة الطلبات الصالحة بينما convert
نقطة نهاية التحويل (من الواضح) Markdown إلى HTML.
يوجد أدناه رمز API الأساسي لاستدعاء نقطتي النهاية. تقوم مكالمة login
بإرجاع سلسلة "Authenticated" فقط ، بينما تقوم استدعاء convert
بإرجاع أي محتوى Markdown قمت بإرساله إلى التطبيق. تقوم طريقة المنزل بإرجاع عبارة "Hello World!" سلسلة.
const express = require("express"); const bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.get('/', function(req, res){ res.send('Hello World!'); }); app.post('/login', function(req, res) { res.send("Authenticated"); }, ); app.post("/convert", function(req, res, next) { console.log(req.body); if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { res.json(["markdown", req.body.content]); } }); app.listen(3000, function() { console.log("Server running on port 3000"); });
نحن نستخدم البرمجيّة الوسيطة body-parser
لتسهيل تحليل الطلبات الواردة إلى التطبيقات. ستجعل البرمجيات الوسيطة جميع الطلبات الواردة متاحة لك ضمن خاصية req.body
. يمكنك الاستغناء عن البرامج الوسيطة الإضافية ولكن إضافتها تجعل من السهل تحليل العديد من معاملات الطلبات الواردة.
يمكنك تثبيت body-parser
ببساطة باستخدام npm:
$ npm install body-parser
الآن بعد أن أصبح لدينا وظائف كعب الروتين الوهمي الخاصة بنا ، سنستخدم Postman لاختبارها. لنبدأ أولاً بنظرة عامة موجزة عن ساعي البريد.
نظرة عامة على ساعي البريد
Postman هي أداة تطوير API تسهل إنشاء وتعديل واختبار نقاط نهاية API من داخل متصفح أو عن طريق تنزيل تطبيق سطح مكتب (تم إهمال إصدار المتصفح الآن). لديه القدرة على عمل أنواع مختلفة من طلبات HTTP ، مثل GET و POST و PUT و PATCH. إنه متاح لأنظمة Windows و macOS و Linux.
إليك لمحة عن واجهة Postman:
للاستعلام عن نقطة نهاية API ، ستحتاج إلى القيام بالخطوات التالية:
- أدخل عنوان URL الذي تريد الاستعلام عنه في شريط URL في القسم العلوي ؛
- حدد طريقة HTTP على يسار شريط URL لإرسال الطلب ؛
- انقر فوق الزر "إرسال".
سيقوم ساعي البريد بعد ذلك بإرسال الطلب إلى التطبيق ، واسترداد أي ردود وعرضه في النافذة السفلية. هذه هي الآلية الأساسية حول كيفية استخدام أداة Postman. في تطبيقنا ، سيتعين علينا أيضًا إضافة معلمات أخرى إلى الطلب ، والتي سيتم وصفها في الأقسام التالية.
باستخدام ساعي البريد
الآن بعد أن رأينا نظرة عامة على Postman ، دعنا نمضي قدمًا في استخدامه لتطبيقنا.
ابدأ تطبيق markdown-api
الخاص بك من سطر الأوامر:
$ node index.js
لاختبار كود API الأساسي ، نجري مكالمات API للتطبيق من Postman. لاحظ أننا نستخدم طريقة POST لتمرير النص لتحويله إلى التطبيق.
يقبل التطبيق حاليًا محتوى Markdown للتحويل عبر معلمة content
POST. هذا نمرره على أنه تنسيق URL مشفر. يقوم التطبيق حاليًا بإرجاع النص الحرفي في تنسيق JSON - حيث يقوم الحقل الأول دائمًا بإرجاع علامة markdown
السلسلة والحقل الثاني يعيد النص المحول. في وقت لاحق ، عندما نضيف كود معالجة Markdown ، فإنه سيعيد النص المحول.
المرحلة 3: إضافة محول Markdown
مع إنشاء سقالة التطبيق الآن ، يمكننا النظر في مكتبة Showdown
JavaScript التي سنستخدمها لتحويل Markdown إلى HTML. Showdown عبارة عن Markdown ثنائي الاتجاه لمحول HTML مكتوب بلغة JavaScript والذي يسمح لك بتحويل Markdown إلى HTML والعكس.
قم بتثبيت الحزمة باستخدام npm:
$ npm install showdown
بعد إضافة كود المواجهة المطلوب إلى السقالة ، نحصل على النتيجة التالية:
const express = require("express"); const bodyParser = require('body-parser'); const showdown = require('showdown'); var app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); converter = new showdown.Converter(); app.get('/', function(req, res){ res.send('Hello World!'); }); app.post('/login', function(req, res) { res.send("Authenticated"); }, ); app.post("/convert", function(req, res, next) { if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); } }); app.listen(3000, function() { console.log("Server running on port 3000"); });
كود المحول الرئيسي موجود في /convert
endpoint كما هو مستخرج وموضح أدناه. سيؤدي هذا إلى تحويل أي نص Markdown تقوم بنشره إلى إصدار HTML وإعادته كمستند JSON.
... } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); }
الطريقة التي تقوم بالتحويل هي converter.makeHtml(text)
. يمكننا تعيين خيارات مختلفة لتحويل Markdown باستخدام طريقة setOption
بالتنسيق التالي:
converter.setOption('optionKey', 'value');
لذلك ، على سبيل المثال ، يمكننا تعيين خيار لإدراج عنوان URL محدد وربطه تلقائيًا دون أي ترميز.
converter.setOption('simplifiedAutoLink', 'true');
كما في مثال Postman ، إذا مررنا سلسلة بسيطة (مثل Google home https://www.google.com/
) إلى التطبيق ، فستعيد السلسلة التالية إذا تم تمكين simplifiedAutoLink
:
<p>Google home <a href="https://www.google.com/">https://www.google.com/</a></p>
بدون الخيار ، سيتعين علينا إضافة معلومات الترميز لتحقيق نفس النتائج:
Google home <https://www.google.com/>
هناك العديد من الخيارات لتعديل كيفية معالجة Markdown. يمكن العثور على قائمة كاملة على موقع Showdown على الويب.
الآن لدينا محول Markdown-to-HTML عامل بنقطة نهاية واحدة. دعونا ننتقل إلى أبعد من ذلك ونضيف المصادقة للحصول على التطبيق.
المرحلة 4: إضافة مصادقة API باستخدام Passport
إن تعريض تطبيقك API للعالم الخارجي دون المصادقة المناسبة سيشجع المستخدمين على الاستعلام عن نقطة نهاية API الخاصة بك دون قيود. سيؤدي هذا إلى دعوة عناصر عديمة الضمير إلى إساءة استخدام واجهة برمجة التطبيقات الخاصة بك ، كما سيؤدي إلى إثقال خادمك بطلبات غير خاضعة للإشراف. للتخفيف من ذلك ، يتعين علينا إضافة آلية مصادقة مناسبة.
سنستخدم حزمة Passport لإضافة المصادقة إلى تطبيقنا. تمامًا مثل البرنامج الوسيط body-parser
الذي واجهناه سابقًا ، Passport هو وسيط مصادقة لـ Node.js. السبب في أننا سنستخدم Passport هو أنه يحتوي على مجموعة متنوعة من آليات المصادقة للعمل مع (اسم المستخدم وكلمة المرور ، Facebook ، Twitter ، وما إلى ذلك) مما يمنح المستخدم المرونة في اختيار آلية معينة. يمكن إسقاط البرامج الوسيطة Passport بسهولة في أي تطبيق Express دون تغيير الكثير من التعليمات البرمجية.
قم بتثبيت الحزمة باستخدام npm.
$ npm install passport
سنستخدم أيضًا الإستراتيجية local
، والتي سيتم شرحها لاحقًا ، للمصادقة. لذا قم بتثبيته أيضًا.
$ npm install passport-local
ستحتاج أيضًا إلى إضافة وحدة تشفير وفك تشفير JWT (JSON Web Token) لـ Node.js التي يستخدمها Passport:
$ npm install jwt-simple
استراتيجيات في جواز السفر
يستخدم Passport مفهوم الاستراتيجيات لمصادقة الطلبات. الإستراتيجيات هي طرق مختلفة تتيح لك مصادقة الطلبات ويمكن أن تتراوح من الحالة البسيطة مثل التحقق من بيانات اعتماد اسم المستخدم وكلمة المرور أو المصادقة باستخدام OAuth (Facebook أو Twitter) أو استخدام OpenID. قبل مصادقة الطلبات ، يجب تكوين الإستراتيجية المستخدمة بواسطة التطبيق.
في تطبيقنا ، سنستخدم نظام مصادقة بسيط لاسم المستخدم وكلمة المرور ، حيث يسهل فهمه ورمزه. يدعم Passport حاليًا أكثر من 300 استراتيجية يمكن العثور عليها هنا.
على الرغم من أن تصميم Passport قد يبدو معقدًا ، إلا أن التنفيذ في الكود بسيط للغاية. فيما يلي مثال يوضح كيفية تزيين نقطة النهاية /convert
للمصادقة. كما سترى ، فإن إضافة المصادقة إلى طريقة بسيطة بما يكفي.
app.post("/convert", passport.authenticate('local',{ session: false, failWithError: true }), function(req, res, next) { // If this function gets called, authentication was successful. // Also check if no content is sent if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); }}, // Return a 'Unauthorized' message back if authentication failed. function(err, req, res, next) { return res.status(401).send({ success: false, message: err }) });
الآن ، جنبًا إلى جنب مع سلسلة Markdown المراد تحويلها ، يتعين علينا أيضًا إرسال اسم مستخدم وكلمة مرور. سيتم التحقق من ذلك باستخدام اسم المستخدم وكلمة المرور للتطبيق الخاص بنا والتحقق منه. نظرًا لأننا نستخدم استراتيجية محلية للمصادقة ، يتم تخزين بيانات الاعتماد في الكود نفسه.
على الرغم من أن هذا قد يبدو وكأنه كابوس أمني ، إلا أنه يعد جيدًا للتطبيقات التجريبية. يؤدي هذا أيضًا إلى تسهيل فهم عملية المصادقة في مثالنا. بالمناسبة ، طريقة الأمان الشائعة المستخدمة هي تخزين بيانات الاعتماد في متغيرات البيئة. ومع ذلك ، قد لا يتفق الكثير من الناس مع هذه الطريقة ، لكنني أجد هذا آمنًا نسبيًا.
يظهر المثال الكامل مع المصادقة أدناه.
const express = require("express"); const showdown = require('showdown'); const bodyParser = require('body-parser'); const passport = require('passport'); const jwt = require('jwt-simple'); const LocalStrategy = require('passport-local').Strategy; var app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); converter = new showdown.Converter(); const ADMIN = 'admin'; const ADMIN_PASSWORD = 'smagazine'; const SECRET = 'secret#4456'; passport.use(new LocalStrategy(function(username, password, done) { if (username === ADMIN && password === ADMIN_PASSWORD) { done(null, jwt.encode({ username }, SECRET)); return; } done(null, false); })); app.get('/', function(req, res){ res.send('Hello World!'); }); app.post('/login', passport.authenticate('local',{ session: false }), function(req, res) { // If this function gets called, authentication was successful. // Send a 'Authenticated' string back. res.send("Authenticated"); }); app.post("/convert", passport.authenticate('local',{ session: false, failWithError: true }), function(req, res, next) { // If this function gets called, authentication was successful. // Also check if no content is sent if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); }}, // Return a 'Unauthorized' message back if authentication failed. function(err, req, res, next) { return res.status(401).send({ success: false, message: err }) }); app.listen(3000, function() { console.log("Server running on port 3000"); });
يتم عرض جلسة ساعي البريد التي تعرض التحويل مع المصادقة المضافة أدناه.
هنا يمكننا أن نرى أننا حصلنا على سلسلة محولة HTML مناسبة من صيغة Markdown. على الرغم من أننا طلبنا فقط تحويل سطر واحد من Markdown ، إلا أن واجهة برمجة التطبيقات يمكنها تحويل قدر أكبر من النص.
بهذا نختتم غزتنا القصيرة في بناء نقطة نهاية API باستخدام Node.js و Express. يعد إنشاء واجهة برمجة التطبيقات موضوعًا معقدًا وهناك فروق دقيقة يجب أن تكون على دراية بها أثناء بناء واحد ، وهو أمر للأسف ليس لدينا وقت هنا ولكن ربما نغطيها في المقالات المستقبلية.
الوصول إلى API الخاص بنا من تطبيق آخر
الآن بعد أن قمنا ببناء API ، يمكننا إنشاء برنامج نصي صغير Node.js سيوضح لك كيفية الوصول إلى واجهة برمجة التطبيقات. على سبيل المثال ، سنحتاج إلى تثبيت حزمة request
npm التي توفر طريقة بسيطة لإنشاء طلبات HTTP. (من المحتمل أن يكون هذا مثبتًا بالفعل.)
$ npm install request --save
فيما يلي رمز المثال لإرسال طلب إلى API الخاص بنا والحصول على الرد. كما ترى ، فإن حزمة request
تبسط الأمر بشكل كبير. الشطب المراد تحويله موجود في متغير textToConvert
.
قبل تشغيل البرنامج النصي التالي ، تأكد من أن تطبيق API الذي أنشأناه سابقًا قيد التشغيل بالفعل. قم بتشغيل البرنامج النصي التالي في نافذة أوامر أخرى.
ملاحظة : نحن نستخدم (back-tick)
لتمديد أسطر JavaScript متعددة لمتغير textToConvert
. هذه ليست اقتباس واحد.
var Request = require("request"); // Start of markdown var textToConvert = `Heading ======= ## Sub-heading Paragraphs are separated by a blank line. Two spaces at the end of a line produces a line break. Text attributes _italic_, **bold**, 'monospace'. A [link](https://example.com). Horizontal rule:`; // End of markdown Request.post({ "headers": { "content-type": "application/json" }, "url": "https://localhost:3000/convert", "body": JSON.stringify({ "content": textToConvert, "username": "admin", "password": "smagazine" }) }, function(error, response, body){ // If we got any connection error, bail out. if(error) { return console.log(error); } // Else display the converted text console.dir(JSON.parse(body)); });
عندما نقوم بتقديم طلب POST إلى واجهة برمجة التطبيقات الخاصة بنا ، فإننا نقدم نص Markdown ليتم تحويله مع بيانات الاعتماد. إذا قدمنا بيانات اعتماد خاطئة ، فسيتم استقبالنا برسالة خطأ.
{ success: false, message: { name: 'AuthenticationError', message: 'Unauthorized', status: 401 } }
للحصول على طلب مخول بشكل صحيح ، سيتم تحويل نموذج Markdown أعلاه إلى ما يلي:
[ 'markdown', `<h1>Heading</h1> <h2>Sub-heading</h2> <p>Paragraphs are separated by a blank line.</p> <p>Two spaces at the end of a line<br /> produces a line break.</p> <p>Text attributes <em>italic</em>, <strong>bold</strong>, 'monospace'. A <a href="https://example.com">link</a>. Horizontal rule:</p>` ]
على الرغم من أننا قمنا بترميز Markdown هنا ، إلا أن النص يمكن أن يأتي من مصادر أخرى مختلفة - ملفات ، ونماذج ويب ، وما إلى ذلك. تظل عملية الطلب كما هي.
لاحظ أننا نرسل الطلب كنوع محتوى application/json
؛ نحتاج إلى تشفير الجسم باستخدام json ، ومن هنا جاءت استدعاء دالة JSON.stringify
. كما ترى ، فإنه يأخذ مثالًا صغيرًا جدًا للاختبار أو تطبيق API.
خاتمة
في هذه المقالة ، شرعنا في برنامج تعليمي بهدف التعلم حول كيفية استخدام Node و js و Express framework لبناء نقطة نهاية API. بدلاً من إنشاء بعض التطبيقات الوهمية بدون أي غرض ، قررنا إنشاء واجهة برمجة تطبيقات تقوم بتحويل صيغة Markdown إلى HTML ، والتي ترسخ أو تتعلم في سياق مفيد. على طول الطريق ، أضفنا المصادقة إلى نقطة نهاية API الخاصة بنا ، ورأينا أيضًا طرقًا لاختبار نقطة نهاية تطبيقنا باستخدام Postman.