Создание Node.js Express API для преобразования 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:
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!» приветствие в браузере, и мы можем приступить к созданию базового API для преобразования Markdown в HTML.
Этап 2: Создание базового API
Основной целью нашего API будет преобразование текста в синтаксисе Markdown в HTML. API будет иметь две конечные точки:
-
/login
-
/convert
Конечная точка login
позволит приложению аутентифицировать действительные запросы, в то время как конечная точка convert
преобразует (очевидно) Markdown в HTML.
Ниже приведен базовый код API для вызова двух конечных точек. Вызов login
просто возвращает строку «Аутентифицировано», а вызов 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.
Обзор почтальона
Postman — это инструмент разработки API, который позволяет легко создавать, изменять и тестировать конечные точки API из браузера или путем загрузки настольного приложения (версия для браузера в настоящее время устарела). Он может выполнять различные типы HTTP-запросов, например, GET, POST, PUT, PATCH. Он доступен для Windows, macOS и Linux.
Вот вкус интерфейса Postman:
Чтобы запросить конечную точку API, вам необходимо выполнить следующие шаги:
- Введите URL-адрес, который вы хотите запросить, в строке URL-адреса в верхней части;
- Выберите метод HTTP слева от строки URL для отправки запроса;
- Нажмите кнопку «Отправить».
Затем Postman отправит запрос в приложение, получит все ответы и отобразит их в нижнем окне. Это основной механизм использования инструмента Postman. В нашем приложении нам также придется добавить в запрос другие параметры, которые будут описаны в следующих разделах.
Использование почтальона
Теперь, когда мы ознакомились с Postman, давайте перейдем к его использованию в нашем приложении.
Запустите приложение markdown-api
из командной строки:
$ node index.js
Чтобы протестировать базовый код API, мы делаем вызовы API к приложению из Postman. Обратите внимание, что мы используем метод POST для передачи текста для преобразования в приложение.
В настоящее время приложение принимает содержимое Markdown для преобразования с помощью параметра POST content
. Это мы передаем как формат с кодировкой 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
, как показано ниже. Это преобразует любой текст 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');
Как и в примере с почтальоном, если мы передаем простую строку (например, 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 в HTML с одной конечной точкой. Давайте двинемся дальше и добавим аутентификацию, чтобы иметь приложение.
Этап 4: Добавление аутентификации API с использованием паспорта
Предоставление API вашего приложения внешнему миру без надлежащей аутентификации побудит пользователей запрашивать вашу конечную точку 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"); });
Сессия Postman, которая показывает преобразование с добавленной аутентификацией, показана ниже.
Здесь мы видим, что у нас есть правильная преобразованная строка HTML из синтаксиса Markdown. Хотя мы запросили преобразование только одной строки Markdown, API может преобразовать больший объем текста.
На этом мы завершаем наш краткий экскурс в создание конечной точки API с использованием Node.js и Express. Создание API — сложная тема, и есть более тонкие нюансы, о которых вы должны знать при его создании, и, к сожалению, у нас нет на это времени, но, возможно, мы рассмотрим их в следующих статьях.
Доступ к нашему API из другого приложения
Теперь, когда мы создали API, мы можем создать небольшой скрипт Node.js, который покажет вам, как можно получить доступ к API. В нашем примере нам нужно будет установить пакет 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-запрос к нашему API, мы предоставляем текст 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 для создания конечной точки API. Вместо того, чтобы создавать какое-то фиктивное приложение без цели, мы решили создать API, который преобразует синтаксис Markdown в HTML, который привязывает или обучает в полезном контексте. Попутно мы добавили аутентификацию в нашу конечную точку API, а также увидели способы протестировать конечную точку нашего приложения с помощью Postman.