[GitHub, Node.JS, Open source] Midmare — свободный от HTTP-Layer модуль Node.js

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
07-Сен-2020 00:31

Midmare — это минималистичная open-source библиотека. Я написал её в достаточно сжатые сроки с целью оптимизировать конкретные процессы в своей компании. Но в результате удалось прийти к решению, потенциал которого значительно превышает изначальную задумку.
В этой статье я расскажу об особенностях и возможностях Midmare, а также поделюсь своим опытом в создании собственной библиотеки.
Предыстория
Продукт, с которым я работаю, сейчас переживает процесс миграции. Пока он не окончен, мы параллельно существуем на двух платформах и отходим от legacy. Я занимаюсь серверной частью веб-приложения для новой платформы. Некоторые процессы приходится постоянно унифицировать с другими командами.
С учетом этих особенностей необходимо было найти гибкое и универсальное решение, чтобы переписать существующий backend. Таким решением стала библиотека Midmare.
Вводные задачи
У меня была задача сделать так, чтобы библиотеку можно было использовать и с TypeScript, и с JavaScript. При этом команда целилась на то, чтобы полностью переписать код с TS на JS для ускорения разработки.
JS не типизирован, поэтому с ним разработка идет значительно быстрее, пусть и менее стабильно. Мы были готовы пойти на такие риски, так как планировали обезопасить себя, написав достаточно тестов.
Сначала неделю-полторы я думал над концепцией, перебирал разные варианты. Пока не пришел к идее, что было бы классно использовать функциональный подход так, чтобы была возможность в любой цепочке исполнения вставить любое звено без последствий.
Я пришел к идее использовать middleware
А именно — сделать цепочку функций промежуточной обработки, которые выполняются друг за другом и реагируют на ошибки друг друга (ошибки, проблемы, изменения данных и тому подобное).
Так у меня получился стек middleware, который по своему принципу похож на Коа. Такая схожесть гарантирует, что остальным библиотеку будет легко использовать. Но в Midmare методов значительно меньше, всего 4. Библиотека Midmare сама по себе минималистичная.
Начало работы
Перед установкой Midmare необходимо скачать и установить Node.js версии 10 и выше. При создании нового проекта нужно также сперва создать package.json с командой npm init.
Установка Midmare выполняется через команду npm install midmare.
Ниже приведен образец инициализации приложения.

Общая инициализация приложения на Midmare

Использование роутеров (промежуточных обработчиков уровня маршрутизатора)
Возможности Midmare
В первую очередь, мы говорим о впечатляющих возможностях декомпозиции кода. Промежуточные функции (middleware) могут не знать друг о друге ничего. Они просто берут данные, обрабатывают и отпускают дальше.
Библиотека Midmare идеально подходит в тех случаях, когда нужно использовать одну систему маршрутизации для разных API — source и destination. То есть когда нужно создать некий общий узел обработки. Но так же можно создавать и более простые приложения.
Приведу несколько примеров, чтобы подчеркнуть возможности Midmare.

Отлов ошибок с помощью промежуточной функции. Он же пример декомпозиции кода

Простая промежуточная функция, закрывающая HTTP-сессию в случае несовпадения маршрутов

Пример обработки какой-либо команды, в данном случае — отправка данных в Redis
Маленькая библиотека делает свою маленькую работу, но при этом ни в чем не ограничивает доступные тебе опции. В Midmare можно подключить по сути всё, что угодно — не ломая голову, как строить архитектуру.
Ключевое преимущество
Ключевое преимущество этой библиотеки — полная отвязка от каких-либо лейеров (HTTP, WS, etc.). Если Koa рассчитан на HTTP-сервер, то Midmare в этом плане не создает ограничений.
Можно даже просто написать терминальную утилиту. С Midmare это удобно, так как мы можем использовать параметры в ``. Как в примере ниже:

Используя Midmare, можно вернуться всё к тому же HTTP-серверу. Подключить его не будет сложностью. Уже есть готовый роутер для HTTP.
При этом также можно спокойно подключать WebSockets. Нужно только инициализировать сам клиент WebSockets. А дальше дело за максимально простым роутингом.

Пример объединения HTTP и WebSockets с Midmare
Такая универсальность устраняет необходимость продумывать разные пути решения одной и той же проблемы в одной программе.
На самом деле, перечислить все возможности реализации довольно трудно, ведь без ограничений к библиотеке применима любая идея.
Готовых библиотек такого формата я не встречал
То есть полного аналога: без низкоуровневых привязок, будь то WebSockets, HTTP или, если обобщать, сетевая связь или программная работа в самой ОС.
Midmare может делать это всё одновременно и буквально в 5–6 строк настройки.
А идея в её основе достаточно простая — построить цепочку выполнения функций с использованием метода next/send для вызова. Если ничего дальше вызывать не нужно, программа остановится. Плюс роутинг, минус HTTP — и мы имеем Midmare.
Зачем использовать эту библиотеку?
Всегда можно написать собственное решение. Конечно, при этом у вас может хромать декомпозиция или сам код (например, может не получиться вклиниться между шагами в цепочке). Если таких огрехов много, то программа, написанная вручную, может прийти к плохому финалу через год–два. Midmare позволяет этого избежать.
Кроме того, слишком много фильтров существует в мире программистов. Кому-то хочется писать на TypeScript, кому-то на JS. Я искал решение, чтобы захватить оба варианта.

Сейчас я стараюсь активно тестировать и дорабатывать Midmare
Большой плюс маленькой библиотеки — её создатель сам же её активно поддерживает.
Свою библиотеку я тестирую каждый день и, соответственно, быстро нахожу подводные камни или недоработки. С маленькой библиотекой любую проблему можно исправить в кратчайшие сроки.
Циклические вызовы — первая из исправленных проблем
Посмотрим на пример ниже:

Допустим, нам нужно добавить в шаг .process(‘/message’) вызов ‘/send’, но в .process(‘/send’) уже содержится вызов ‘/message’. Тогда Шаг №2 будет вызывать Шаг №1. При этом в Шаге №1 будет каждый раз срабатывать вызов Шага №2 — и так по кругу.
Когда работаешь над созданием библиотеки, такие проблемы нужно вылавливать, показывать пользователям, объяснять, чем это чревато.
В данном случае у нас возникнет ошибка Maximum call stack size exceeded и JS упадет в ответ на многократный рекурсивный вызов одной и той же функции.
Решение такой проблемы в этой библиотеке: Сохранение истории путей в одном контексте. То есть каждый вызов `ctx.send` или `app.send` имеет свою историю вызовов.
Поскольку в Midmare есть обработка этого момента, библиотека выдаст ошибку в случае циклического вызова.
Может быть ситуация, в которой циклический вызов нужен. Например, две промежуточные функции обрабатывают одни и те же данные по-разному, потому что существует возможность выхода из цикла. То есть, когда в одной из функций есть if-else, который отработает в else и проигнорирует циклический вызов.
На случай, если в реализации будет требоваться цикличность, в Midmare существует опция установить игнорирование ошибки через `ignoreCycleError: true`.

Библиотека ждёт своё комьюнити
В такую pure-библиотеку в принципе нет смысла что-либо добавлять. Было бы неплохо добавить возможность подключать плагины, но с middleware это можно решить и без нового функционала.
Если в конкретном случае не хватает какой-то обработки, её можно самостоятельно дописать в условные 4 строчки. Как в примере с функцией для закрытия HTTP-сессии:

Все дополнительные обработки можно вынести в отдельный репозиторий. Или разнести роутеры по репозиториям. Подключаться и обрабатываться всё будет так же.
Что библиотеке действительно не помешало бы на сейчас, так это сообщество, которое бы создавало на основе библиотеки свои инструменты. Поэтому я приглашаю комьюнити вносить свой вклад в развитие библиотеки. Присоединяйтесь и тестируйте.
Автор: Иван Петушинский, Senior Node.js Developer
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_github, #_node.js, #_open_source, #_parimatch_tech, #_nodejs, #_mindmare, #_open_source, #_github, #_backend, #_product_development, #_blog_kompanii_parimatch_tech (
Блог компании Parimatch Tech
)
, #_github, #_node.js, #_open_source
Профиль  ЛС 
Показать сообщения:     

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

Текущее время: 22-Ноя 17:33
Часовой пояс: UTC + 5