Статьи

Параллельное сравнение Express, Koa и Hapi.js

Если вы разработчик Node.js, скорее всего, в какой-то момент вы использовали Express.js для создания своих приложений или API. Express.js — это очень популярный фреймворк Node.js, на котором даже есть некоторые другие фреймворки, такие как Sails.js , kraken.js , KeystoneJS и многие другие . Тем не менее, среди этой популярности, в мире JavaScript привлекает внимание множество других фреймворков, таких как Koa и hapi.

В этой статье мы рассмотрим Express.js, Koa и hapi.js — их сходство, различия и варианты использования.

Фон

Давайте сначала представим каждую из этих структур отдельно.

Express.js

Express.js описывается как стандартная серверная структура для Node.js. Он был создан TJ Holowaychuk , приобретен StrongLoop в 2014 году и в настоящее время поддерживается инкубатором Фонда Node.js. За последний год его загрузили около 170 с лишним миллионов раз , и в настоящее время нет сомнений, что это самая популярная среда Node.js.

Коа

Разработка Koa началась в конце 2013 года теми же ребятами из Express. Это называется будущее Экспресс. Коа также описывается как гораздо более современная, модульная и минималистичная версия платформы Express.

Hapi.js

Hapi.js был разработан командой Walmart Labs (во главе с Эраном Хаммером ) после того, как они попробовали Express и обнаружили, что он не работает для их требований. Первоначально он был разработан на основе Express, но со временем он превратился в полноценный фреймворк.

Интересный факт: хапи это сокращение от Http API сервера.

философия

Теперь, когда у нас есть некоторые сведения о фреймворках и о том, как они были созданы, давайте сравним каждую из них на основе важных концепций, таких как их философия, маршрутизация и так далее.

Примечание: все примеры кода приведены в ES6 и используют версию 4 Express.js, 2.4 Koa и 17 для hapi.js.

Express.js

Express был создан, чтобы быть простой, незавершенной веб-структурой. Из его GitHub README :

Философия Express заключается в предоставлении небольшого и надежного инструментария для серверов HTTP, что делает его отличным решением для одностраничных приложений, веб-сайтов, гибридов или общедоступных API-интерфейсов HTTP.

Express.js минимален и не обладает множеством функций из коробки. Это не требует таких вещей, как структура файла, ORM или шаблонизатор.

Коа

Хотя Express.js минимален, Koa может похвастаться гораздо более минималистичным размером кода — около 2 тыс. LOC . Его цель — позволить разработчикам быть еще более выразительными. Как и Express.js, его можно легко расширить с помощью существующих или пользовательских плагинов и промежуточного программного обеспечения. Он более футуристичен в своем подходе, поскольку он в значительной степени опирается на относительно новые функции JavaScript, такие как генераторы и async / await .

Hapi.js

Hapi.js больше фокусируется на конфигурации и предоставляет гораздо больше функций из коробки, чем Koa и Express.js. Эран Хаммер , один из создателей хапи, описал причину правильного построения фреймворка в своем блоге :

Хапи был создан вокруг идеи, что конфигурация лучше, чем код, бизнес-логика должна быть изолирована от транспортного уровня, и что нативные конструкции узлов, такие как буферы и потоки, должны поддерживаться как объекты первого класса.

Запуск сервера

Запуск сервера — это одна из основных вещей, которую нам нужно сделать в наших проектах. Давайте рассмотрим, как это можно сделать в разных рамках. Мы запустим сервер и прослушаем порт 3000 в каждом примере.

Express.js

const express = require('express'); const app = express(); app.listen(3000, () => console.log('App is listening on port 3000!')); 

Запустить сервер в Express.js так же просто, как запросить express пакет, инициализировать express приложение для переменной app и вызвать метод app.listen() , который является просто оболочкой для собственного Node.js http.createServer (). метод.

Коа

Запуск сервера в Koa очень похож на Express.js:

 const Koa = require('koa'); const app = new Koa(); app.listen(3000, () => console.log('App is listening on port 3000!')); 

Метод app.listen() в Koa также является оболочкой для http.createServer() .

Hapi.js

Запуск сервера в hapi.js — это далеко не то, к чему многие из нас могут привыкнуть из Express:

 const Hapi = require('hapi'); const server = Hapi.server({ host: 'localhost', port: 3000 }); async function start() { try { await server.start(); } catch (err) { console.log(err); process.exit(1); } console.log('Server running at:', server.info.uri); }; start(); 

В приведенном выше блоке кода сначала требуется пакет hapi , затем создается экземпляр сервера с помощью Hapi.server() , который имеет один аргумент объекта конфигурации, содержащий параметры хоста и порта. Затем мы запускаем сервер с помощью асинхронной функции server.start() .

В отличие от Express.js и server.start() функция server.start() в hapi не является оболочкой для собственного http.createServer() . Вместо этого он реализует свою собственную логику.

Приведенный выше пример кода взят с веб-сайта hapi.js и показывает важность, которую создатели hapi.js придают конфигурации и обработке ошибок.

Маршрутизация

Маршрутизация является еще одним ключевым аспектом современных веб-приложений. Давайте определим маршрут /hello для простого приложения Hello World в каждой среде, чтобы понять, как для них работает маршрутизация.

Express.js

 app.get('/hello', (req, res) => res.send('Hello World!')); 

Создание маршрутов в Express так же просто, как вызов объекта app с помощью требуемого метода HTTP. Синтаксис app.METHOD(PATH, HANDLER) , где PATH — это путь на сервере, а HANDLER — это функция, которая вызывается при app.METHOD(PATH, HANDLER) пути.

Коа

Koa не имеет своего собственного маршрутизатора в комплекте с ним, поэтому нам придется использовать промежуточное программное обеспечение для маршрутизации приложений Koa. Два общих варианта маршрутизации — это koa-route и koa-router . Вот пример использования koa-route:

 const route = require('koa-route'); app.use(route.get('/hello', ctx => { ctx.body = 'Hello World!'; })); 

Мы сразу видим, что Коа нужно, чтобы каждый маршрут определялся как промежуточное ПО в приложении. ctx — это объект контекста, который содержит объекты request и response Node. ctx.body — это метод в объекте response можно использовать для установки тела ответа в виде string , Buffer , Stream , Object или null . Вторым параметром для метода маршрута может быть асинхронная или генераторная функция, поэтому использование обратных вызовов сокращено.

Hapi.js

 server.route({ method: 'GET', path:'/hello', handler: function (request, h) { return 'Hello world!'; } }); 

Метод server.route() в hapi принимает один объект конфигурации со следующими параметрами: method , path и handler . Вы можете увидеть документацию по маршрутизации в хапи здесь .

Параметр request в функции-обработчике является объектом, который содержит детали запроса пользователя, а параметр h описан как набор инструментов ответа.

Промежуточное

Одна из основных концепций, к которой привыкли разработчики Node, — это работа с промежуточным программным обеспечением. Функции промежуточного программного обеспечения — это функции, которые находятся между запросами и ответами. Они имеют доступ к объектам request и response и могут запускать следующее промежуточное программное обеспечение после их обработки. Давайте посмотрим, как они определены в различных инфраструктурах, реализовав простую функцию, которая регистрирует время выполнения запроса к серверу.

Express.js

 app.use((req, res, next) => { console.log(`Time: ${Date.now()}`); next(); }) 

Зарегистрировать промежуточное ПО в Express.js так же просто, как app.use() промежуточное ПО с объектом приложения с помощью функции app.use() . Вы можете прочитать больше о промежуточном программном обеспечении в Express.js здесь .

Коа

 app.use(async (ctx, next) => { console.log(`Time: ${Date.now()}`); await next(); }); 

Регистрация промежуточного программного обеспечения в Koa похожа на Express.js. Основные отличия заключаются в том, что объект контекста ( ctx ) используется вместо объектов request и response в Express.js, а Koa использует современную парадигму async / await для определения функции промежуточного программного обеспечения.

Hapi.js

 server.ext('onRequest', (request, h) => { console.log(`Time: ${Date.now()}`); return h.continue; }); 

В hapi.js есть определенные точки расширения в жизненном цикле запроса . Метод server.ext() регистрирует функцию расширения, которая server.ext() в определенный момент жизненного цикла запроса. Вы можете прочитать больше об этом здесь . Мы используем onRequest расширения onRequest в приведенном выше примере для регистрации функции промежуточного программного обеспечения (или расширения).

использование

Из сравнений и примеров кода, которые мы видели выше, ясно, что Express и Koa являются наиболее похожими, поскольку hapi.js является структурой, которая отклоняется от нормы, к которой привыкли разработчики Node.js. Следовательно, hapi.js может быть не лучшим выбором при попытке создать быстрое и простое приложение, так как привыкание займет некоторое время.

На мой взгляд, Express по-прежнему является отличным выбором при создании приложений малого и среднего размера. Управлять им может быть довольно сложно для очень больших приложений, поскольку он не обладает модульностью, встроенной в него hapi.js, с поддержкой пользовательских плагинов и уникальным методом маршрутизации . Тем не менее, в последнее время высказывались некоторые предположения относительно будущего Express.js, так как TJ объявил, что он больше не работает над ним, и о снижении скорости, с которой отправляются обновления . Хотя он довольно стабилен и не скоро уйдет. У этого также есть большое сообщество разработчиков, создающих различные расширения и плагины для этого.

Как и Express.js, Koa хорошо подходит для многих простых проектов Node.js. Он состоит только из минимума (у него нет встроенного промежуточного программного обеспечения) и поощряет разработчиков добавлять то, что им нужно, путем создания или использования доступного внешнего промежуточного программного обеспечения. Он использует современные функции генератора JavaScript и активно использует async / await, что делает его своего рода футуристическим в своем подходе. Его каскадный паттерн промежуточного программного обеспечения также хорош, поскольку он делает реализацию и понимание потока промежуточного программного обеспечения в ваших приложениях очень простым. Koa, вероятно, не будет отличным выбором для вас, если вы еще не готовы принять новые блестящие вещи, такие как функции генератора, или если вы не хотите тратить некоторое время на создание всего необходимого промежуточного программного обеспечения. Поддержка сообщества для Koa быстро растет, так как для него уже создано большое количество внешнего промежуточного программного обеспечения (некоторые из которого сделаны основной командой Koa) для выполнения общих задач, таких как маршрутизация, ведение журналов и так далее.

Hapi.js — это верный выбор, если вы и ваша команда предпочитаете тратить больше времени на настройку, чем на кодирование функций. Это было построено, чтобы быть модульным и для больших заявлений с большими командами. Он поддерживает архитектуру микросервисов, поскольку различные части вашего приложения могут быть собраны в виде плагинов и зарегистрированы на вашем сервере перед его запуском. Hapi.js поддерживается крупными компаниями, такими как Auth0 и Lob, поэтому у него впереди довольно хорошее будущее, и в ближайшее время он не уйдет. Ему также доверяют некоторые громкие имена, как видно на их странице сообщества .

Hapi.js имеет гораздо больше функций из коробки, чем Koa и Express.js, таких как поддержка аутентификации, кэширования, регистрации, проверки и т. Д., Что делает его более похожим на полноценную среду. Вы можете проверить их учебные страницы, чтобы получить представление о функциях, которые они предоставляют. Пока еще не очень много проектов и плагинов с открытым исходным кодом, созданных для hapi.js, поэтому разработчикам, возможно, придется проделать большую работу, если они планируют расширить его основные функциональные возможности.

Вывод

Все три фреймворка являются отличным выбором при запуске новых проектов, но в конечном итоге ваш выбор будет зависеть от требований проекта, членов вашей команды и уровня гибкости, который вы ищете.