Руководство по сверхбыстрой разработке веб-фреймворка для Node.js
Веб-фреймворки упрощают создание веб-приложений Node.js. Они избавляют от догадок при обработке запросов и HTTP-методов. Они обеспечивают динамическую визуализацию HTML, шаблоны и архитектурные шаблоны, упрощающие разработку приложений. С годами Express стал предпочтительным веб-фреймворком Node.js. Но всегда ли он лучший? Создатели Fastify считают, что это не так. Я смог лично испытать Fastify во время недавнего проекта. Я на их стороне или нет?
Совсем недавно мы с моей командой Node.js работали над проектом системы вознаграждений для игроков в различные бесплатные онлайн-игры. Клиент хотел радикально обновить все приложение. Во всех смыслах и целях мы должны были разработать совершенно новую версию системы.
Одним из основных требований проекта было увеличение скорости работы системы. В приложении было много пользователей, которые совершали множество действий. Метрика запросов в секунду имела особое значение.
Нашей естественной средой выбора для Node.js был Express. Он прост в освоении, очень хорошо документирован и очень гибок. Но поскольку скорость должна была быть таким важным фактором, мы решили поближе рассмотреть другие варианты, чтобы провести правильное сравнение скорости.
Достаточно скоро мы начали рассматривать фреймворк, название которого призвано заставить вас сразу же подумать о скорости — Fastify.
Что такое Фастфай?
Fastify — это библиотека Node.js, созданная Маттео Коллиной и Дэвидом Марком Клементсом в конце 2016 года. Последняя версия — 4.7.0. Если вас интересует история выпусков, ознакомьтесь с информацией о долгосрочной поддержке и соответствующими примечаниями к выпуску.
По словам создателей:
Fastify родился из-за желания создать универсальную веб-инфраструктуру, которая обеспечила бы удобство для разработчиков без ущерба для пропускной способности и производительности.
Fastify скачивают более 700 000 раз в неделю. На данный момент он используется примерно в 25 000 проектах. Многие компании уже присоединились к нам, в том числе такие гиганты, как Microsoft. Вот некоторые из компаний, которые используют Fastify.
Повышение производительности — тест скорости
Когда клиент выразил заинтересованность в приоритизации скорости приложений, мы решили попробовать Fastify. Говорят, что это один из самых быстрых веб-фреймворков. Естественно, мы не могли поднять его только на основе репутации.
Мы постарались найти как можно больше источников исследований по теме Fastify. Тогда мы решили провести тесты самостоятельно.
С этой целью мы использовали инструмент сравнительного анализа wg/wrk. Мы сравнили Fastify и Express в 10 независимых тестах. Мы ожидали, что Fastify будет быстрее, но нам нужна была подробная информация, чтобы решить, стоит ли менять структуру Node.js.
Сравнение включало ряд факторов:
- Запросов в секунду
- Количество запросов, обслуженных за 30 секунд
- Перевод в секунду
- Средняя задержка
Вот наши данные теста Fastify:
Сравнение Fastify и Express — часть 1
Сравнение Fastify и Express — часть 2
Общие результаты теста скорости
В каждом отдельном тесте Fastify доказал свое превосходство. В среднем платформа работала примерно на 25 % лучше, чем Express.
Наши выводы и удивили, и впечатлили нас. Они повлияли на наше решение перейти на Fastify. Однако вряд ли они были единственным фактором.
Зачем использовать Fastify?
По нашим наблюдениям, преимущества Fastify можно разделить на четыре категории.
Производительность
Мы уже говорили о скорости. Но Fastify также обладает высокой масштабируемостью, что делает фреймворк подходящим как для небольших, так и для крупных проектов. Формат JSON автоматически анализирует функции Fastifiy, обеспечивая быструю маршрутизацию пакетов данных по сети. Это то, что делает фреймворк молниеносным.
Ремонтопригодность
Fastify — это веб-фреймворк с низкими накладными расходами, который минимизирует затраты на обслуживание всего приложения. Кроме того, это веб-фреймворк, ориентированный на безопасность, который гарантирует систему автоматической безопасности и проверки данных.
Гибкость
Fastify поддерживает TypeScript, сотрудничает с AWS Lambda и взаимодействует с его API через адаптер GraphQL. В результате он отлично подходит для разработки веб-приложений, а также для разработки интерфейса API.
Простота разработки
Одним из самых больших преимуществ Fastify в бессерверных приложениях является простота разработки. В вашей локальной среде вы всегда будете запускать приложение Fastify напрямую, без необходимости использования каких-либо дополнительных инструментов, в то время как тот же код будет выполняться на выбранной вами бессерверной платформе с дополнительным фрагментом кода.
Как вы думаете, может ли Fastify стать технологией для вашего следующего проекта?
Вы хотите эффективно использовать ресурсы вашего сервера, обслуживая максимально возможное количество запросов? Вы хотите сделать все это, не жертвуя проверками безопасности и удобной разработкой?
Fastify был сделан для этого сценария.
Проект, о котором я упоминал ранее, является прекрасным примером такого сценария. Клиент ожидал, что приложением будет пользоваться огромное количество людей. И поскольку мы хотели, чтобы новая версия была определенным обновлением версии 1, когда речь шла о производительности, переход с Express на Fastify был логичным шагом.
Когда не использовать Fastify?
Естественно, у всего есть свои плюсы и минусы — Fastify не исключение. По состоянию на 2022 год этот фреймворк не получил широкого распространения в отрасли. Он получает все большее распространение, но его использование все еще скромно по сравнению с Express или Nest.
В дополнение к этому, будучи довольно молодым проектом, документация не так обширна, как можно было бы ожидать от более зрелых фреймворков. Поддержка сообщества так себе. Если вы планируете использовать такую библиотеку, как паспорт.js, вы обнаружите, что она не работает с Fastify. Убедитесь, что Fastify совместим со всеми остальными программами, которые вы хотите использовать.
Если вы неопытный разработчик, ищущий работу, вы можете обнаружить, что очень немногие работодатели в настоящее время ищут разработчиков, которые конкретно разбираются в Fastify. Следовательно, вам может быть лучше пойти на что-то более популярное.
Однако, если вы уже знакомы с Express, изучение Fastify может дать вам дополнительные возможности для использования в вашем проекте и даст вам другой взгляд на веб-разработку в Node.js. Его архитектура действительно выделяется, и уже одно это делает его достойным внимания. Но об этом позже.
Практическое руководство по ускорению
Если вы считаете, что Fastify — это что-то для вас, оставайтесь с нами, потому что мы собираемся продемонстрировать, как вы можете реализовать его, чтобы он мог поддерживать ваш собственный проект.
Выполнение
Мы собираемся сделать простой проект Fastify. Реализация Fasitfy очень похожа на то, что вы могли испытать с Express.js.
Начнем с реализации основных модулей: маршрутизатора, приложения и сервера.
Для этого мы воссоздадим три файла:
- server.js — основной скрипт приложения,
- app.js — скрипт, в котором мы создаем экземпляр сервера Fastify Node,
- router.js — Fastify экземпляр маршрутизатора, который помогает нам инкапсулировать маршруты и подключаемые модули.
Всего в процессе мы создадим четыре файла ts: server.ts, app.ts, router.ts и routing.ts.
Для Server.ts мы просто используем нашу функцию createApp из app.ts. Начнем с определения порта, который будет прослушиваться сервером. Файл также включает простой пример использования регистратора Fastify.
import { createApp } from “./app”; (async () => { const app = createApp(); const port = 1337; app.listen({ port }, (err: Error) => { if (err) process.exit(1); app.log.info(`listening on port: ${port}`); }); })();
Файл app.ts — это сердце нашего кода. Здесь мы создаем функцию createApp, которая инициализирует экземпляр Fastify. Здесь мы также регистрируем плагины через app.register (в показанном примере регистрируются cors, Helmet и Swagger). Здесь же прописан роутер.
import fastify, { FastifyInstance } from "fastify"; import helmet from "fastify-helmet"; import cors from "fastify-cors"; import fastifySwagger from "fastify-swagger"; import { createRouter } from "./router"; function createApp() { const app: FastifyInstance = fastify({ logger: true }); const router = createRouter(); app.register(cors); app.register(helmet); app.register(fastifySwagger); app.decorateReply("basicInfo", null); app.register(router, { prefix: "/api" }); app.ready((err) => { if (err) throw err; }); return app; } export { createApp };
Router.ts определяет способ обработки клиентских запросов конечными точками приложения. Маршрутизатор собирает маршруты для всех функций. В приведенном ниже примере мы регистрируем usersRouting в маршрутизаторе. Передаем роутер в app.js. Там же мы его и регистрируем.
import { FastifyInstance, FastifyPluginOptions } from “fastify”; import { usersRouting } from “./routing”; export const createRouter = () => ( // ROUTES_DEPENDENCIES fastify: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error | undefined) => void,) => { fastify.register(usersRouting, { prefix: "/users" }); fastify.get("/health", (_req, reply) => { reply.status(200).send({ status: "200 - ok" }); }); // ROUTES_CONFIG done(); };
Существует также routing.ts. Он обрабатывает маршрутизацию для пользователей. Мы используем его для определения каждой конечной точки, связанной с пользователями. В примере показано, как можно определить конечную точку получения.
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; export const usersRouting = () => ( fastify: FastifyInstance, done: (err?: Error | undefined) => void) => { fastify.get("/", (_req: FastifyRequest, replay: FastifyReply) => { replay.status(200).send("User found!"); }); done(); };
Плагины Fastify
Одним из наиболее важных изменений, которые приносит Fastify, является замена промежуточного программного обеспечения плагинами. Fastify действительно имеет мощную архитектуру плагинов. Что это за плагины?
Плагин Fastify может быть набором маршрутов, декоратором сервера или чем угодно. Допустим, нам нужно отправить запросы к базе данных из различных модулей приложения. Нужно ли нам подключаться к базе данных, экспортировать соединение, а затем импортировать его в какие-либо модули, в которых нам нужно его использовать? Это работает, но приводит к спагетти-коду.
Именно здесь система плагинов Fastify сияет больше всего. Это позволяет нам внедрять наши зависимости в экземпляр Fastify, а затем использовать их везде, где у нас есть доступ к экземпляру. Это также помогает легко перейти от монолитной структуры к микросервисам, поскольку каждый сервис может быть отдельным плагином.
Экосистема подключаемых модулей Fastify постоянно растет. Возможно, уже есть подключаемый модуль для вашей любимой базы данных, языка шаблонов или даже функций.
Вот несколько примеров:
- cors –> Fastify-cors,
- шлем -> Fastify-шлем,
- express-jwt -> Fastify-jwt,
- multer -> Fastify-multer,
…. и многое другое!
Вот полный список всех основных плагинов Fastify.
Получите максимальную отдачу от Fastify
Fastify также имеет ряд дополнительных функций, которые позволяют вам делать еще больше.
Проверка
Fastify использует Ajv под капотом, что позволяет вам определять правила проверки со схемой JSON.
Ведение журнала
Fastify использует быстрый и гибкий регистратор: pino. Экземпляр регистратора доступен в экземпляре сервера Fastify (например, Fastify.log.info(“…”)) и во всех объектах запроса (например, request.log.info(“…”));
Использование регистратора просто. Вам просто нужно включить его, потому что он отключен по умолчанию:
const fastify = require('fastify')({ logger: true })
Затем вы можете использовать его следующим образом:
fastify.get("/", (request, reply) => { request.log.info("Info about request"); reply.send({ message: "hello world" }); });
Обработка ошибок
Fastify предоставляет метод setErrorHandler(), который позволяет явно указать функцию для обработки ошибок. Кроме того, вы можете указать различные обработчики ошибок Fastify с помощью подключаемых модулей.
Fastify пытается перехватить как можно больше необработанных ошибок, не снижая производительности. Это включает в себя:
- синхронные маршруты: app.get(‘/’, () =› { throw new Error(‘kaboom’) })
- асинхронные маршруты: app.get(‘/’, async() =› { throw new Error(‘kaboom’) })
Декораторы
Они позволяют нам настраивать основные объекты Fastify, такие как сам экземпляр сервера и любые объекты запроса и ответа, используемые в течение жизненного цикла HTTP-запроса. API декораторов можно использовать для присоединения любого типа свойств к основным объектам, например. функции, простые объекты или собственные типы.
Ускорьте учебные ресурсы
Хотите продолжить изучение Fastify? Есть много интересных ресурсов, которые могут вам помочь:
- Конечно, вам нужно начать с официального веб-сайта Fastify, на котором есть документация, тесты и многое другое.
- В менеджере пакетов для Node.js есть страница Fastify с массой полезной информации, включая версии, зависимости, руководства и многое другое.
- Место, где можно найти последние дополнения к кодовой базе Fastify framework.
На странице npm для Fastify содержится масса ценной информации о фреймворке
Fastify и тенденции веб-разработки
Fastify постоянно развивается. Фреймворк Fastify написан на ванильном JavaScript, и поэтому такие определения типов не так просто поддерживать; однако, начиная с версии 2 и выше, сопровождающие и участники приложили огромные усилия для улучшения типов.
Система Fastify Type
Система типов была изменена в Fastify версии 3. Новая система типов вводит общие ограничения и значения по умолчанию, а также новый способ определения типов схемы, таких как тело запроса, строка запроса и многое другое!
Поскольку команда работает над улучшением синергии фреймворка и определения типов, иногда некоторые части API не будут типизированы или могут быть введены неправильно. Вот почему он очень совместим с Typescript.
Fastify — выводы и извлеченные уроки
Учитывая, насколько разработчики любят Express, можно задаться вопросом: действительно ли нам нужен еще один веб-фреймворк для Node.js?
Мое личное мнение однозначно: ДА. Здоровая конкуренция всегда стимулирует рост, что приводит к бесконечному поиску более быстрых, лучших и эффективных решений.
У Fastify, безусловно, есть задатки отличного фреймворка. Я уже считаю его отличным выбором как для веб-разработки, так и для разработки API по ряду причин:
- Это быстро, экономично и поддерживает TypeScript из коробки. Последнее является большим бонусом для крупных коммерческих проектов.
- Он отлично работает с различными инновационными технологиями, распространенными в современной веб-разработке, такими как AWS Lambda или GraphQL.
- Он использует свои сильные стороны, специализируясь на эффективном и быстром управлении ресурсами вашего сервера.
Тем не менее, старый добрый Express все еще здесь, и мы все можем на него положиться. В конце концов, нет никакой веской причины постоянно ограничивать себя одним фреймворком и избегать всех новичков. С другой стороны, вы не должны внезапно впадать в безумие и рефакторить каждое веб-приложение для Fastify.
В ближайшее время можно с уверенностью сказать, что Fastify не обгонит Express по популярности (Express с его 25 млн загрузок огромен), но я думаю, что он обязательно вырастет, и если не будет найден какой-то новый «конкурент», однажды он может стать таким же популярным, как Express. Конечно, кажется, что у него есть все, что нужно.
Я надеюсь, что к тому времени, когда вы начнете свой следующий проект Node.js, вы достаточно изучите Fastify, чтобы сделать осознанный выбор, подходит ли он для данного случая! До встречи в другой статье! До свидания, Фастфай!
Дополнительные материалы на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord.
Хотите масштабировать запуск своего программного обеспечения? Ознакомьтесь с разделом Схема.