Выбор технологического стека для digital-продукта в 2024 году

e72a4dc3363125fc242ac32da76d62f2.png

Стек технологий для запуска нового продукта в компании обычно выбирается исходя из того, с чем команда работала до этого и сколько наработок уже имеется.

Однако если вы свободны от необходимости использования какого-либо наследия (набираете новую команду или ищете актуальные технологии для изучения), то эта статья поможет вам выбрать, что стоит использовать для запуска продукта или сервиса. 

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

Бэкенд как основа

Node.js бэкенды (Express, Koa, Nest и т. д)

Начнем с самых горячих технологий на текущий момент. Количество проектов, работающих на Node.js, сейчас растет очень активно. Этому способствовал как рост экосистемы, так и привлекательность использования одного языка на клиенте и сервере. Раньше Node.js в больших проектах использовался только для отдельных сервисов — бэкенды для чатов, уведомлений, получения быстрочитаемых данных. Однако благодаря развитию инструментов и сообщества JavaScript / TypeScript стало достаточно удобно использовать Node.js и как основную технологию для больших веб-проектов.

Наиболее популярной базой данный в пару к JS-фреймворкам стала MongoDB. Дело в том, что Node.js обрабатывает запросы в одном потоке. Соответственно, приложению жизненно необходимо как можно меньше думать и как можно быстрее получать данные, чтобы не блокировать запросы других пользователей. Возможность хранить ненормализованные JSON-данные и быстро их считывать идеально сочетается с этим требованием. Однако в какой-то момент так называемые MERN-стеки (Mongo-Express-React-Node) стали настолько популярными, что использовались и там, где это явно не нужно, из-за чего компании могли сталкиваться с проблемами роста.

С какими проблемами?

Например, росло количество сущностей в проекте и их связность, возникала необходимость комплексных запросов и нормализации данных для разъезда на микросервисы — и тут уже Mongo становилось не таким уж хорошим решением.

Сейчас все чаще появляются вакансии со стеком Node.js + PostgreSQL. Дело в том, что до недавнего времени библиотеки для работы с SQL-базами в JS-экосистеме были не слишком зрелыми по сравнению с другими языками и стеками. Но сейчас появилось несколько перспективных ORM-библиотек: Prisma, Sequelize и другие. И это довольно важно для развития JS-стека как инструмента для не только дешевой, но и быстрой разработки. PostgreSQL не просто так является любимой базой данных разработчиков — это универсальное Production-Deady решение, которое покрывает требования к производительности и консистентности данных.

У нас в MyGig.ru Node.js является основным стеком для всей платформы. Для меня, как для человека, который много лет писал приложения на Ruby on Rails и Python + Django, некоторые задачи, решаемые разработчиками, кажутся слишком низкоуровневыми — довольно часто изобретаются абстракции и инструменты там, где в более зрелых фреймворках люди используют готовыми решения. Именно поэтому мне Node.js-стеки кажутся подходящими скорее для однозадачных микросервисов, чем для больших приложений с комплексной бизнес-логикой.

Признаю, что популярность Node.js-стеков привела к бурному развитию инструментов и методологий. Так, для больших приложений уже можно использовать Nest.js, который предлагает понятную структуру, философию и архитектурные паттерны, учитывающие особенности технологии. Все это избавляет разработчиков от необходимости изобретать велосипед и облегчает ввод новых кадров.

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

Python + Django/Flask/FastAPI

Этот стек пережил второе рождения с популяризацией профессий в области Data Science. Наличие множества популярных библиотек для работы с данными и машинным обучением (Pandas, Numpy, Keras и TensorFlow) вызвало желание сократить количество используемых технологий в проектах. Однако популярность Python изначально основана на том, что это довольно простой язык для изучения, поэтому он используется не только в Data Science и веб-разработке — например, его все чаще выбирают в качестве первого языка программирования в школах и университетах.

Посмотрим на наиболее популярные фреймворки на Python.

  1. Django. Это целый комбайн, включающий из коробки почти все, что может понадобиться для современного веб-бэкенда: от авторизации и аутентификации до ORM и автоматически генерируемой CMS. В совокупности с отсутствием необходимости сочинять абстракции это позволяет небольшим командам запускать проекты в кратчайшие сроки. Мой опыт с поднятием проектов с нуля до большого продакшена используя Django я могу охарактеризовать только положительно. Однако и некоторые проблемы роста тоже существуют: Django ориентирован на разработку монолитов, что дает быстрый старт и отлично подходит для малых и средних проектов. Для больших систем же со временем Django может показаться обузой (но до таких размеров проект еще должен дорасти).

  2. Flask. Простой фреймворк, который отлично подойдет для небольших микросервисов. Например, он часто используется для создания API для запросов к ML-моделям.

  3. FastAPI. Довольно молодой фреймворк для разработки API, который быстро набрал популярность в Python-сообществе за счет того, что имплементирует в себе многие современные решения как с точки зрения веб-технологий (GraphQL, WebSocket), так и с точки зрения использования преимуществ последних версий Python (асинхронный код, типизация). Отличный выбор как для микросервисов, так и для более крупных API-first проектов.

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

Если говорить о недостатках, то наиболее часто можно услышать про специфику интерпретатора Python, в частности GIL (Global Interpreter Lock), не позволяющий эффективно реализовать многопоточность в некоторых задачах (что, тем не менее, отчасти решаемо).

Python поддерживает асинхронный подход, однако не так эффективен в этом, как тот же Node.js. Но наличие такой возможности нельзя поставить в минус, ведь не меняя язык вы можете оптимизировать ваши I/O-интенсивные задачи.

Зрелость инструментов для веб-разработки, популярность Python в AI и Data Science, простота изучения и доступность специалистов — все это делает Python-стеки отличным выбором для старта проекта любого масштаба.

Ruby on Rails

Я люблю Ruby всем сердцем и отдал ему большую часть своей карьеры разработчиком. В 2010-х Rails был очень популярным выбором из-за скорости разработки и своей философии, которая вырастила много качественных разработчиков. Речь идет про подход Convention over Configuration, который уменьшает количество технологических решений, принимаемых разработчиком, позволяя ему больше концентрироваться на бизнес-задаче, а не на ее реализации. Это же в свою очередь стало и главной темой для критиков Rails:   ощущение, что все работает на каком-то невидимом глазу волшебству уменьшает возможность контроля и усложняет отладку.

Ruby on Rails оказал огромное влияние на всю веб-разработку. Многие подходы копировались (и до сих пор копируются) на другие технологические базы. Популярность тестов в веб-разработке, использование MVC-подобных паттернов, метапрограмирование, ActiveRecord ORM и многие другие вещи, облегчающие разработку во многих популярных веб-фреймворках, получили свое развитие благодаря Rails и его эффективности как инструмента.

Не смотря на всю мою любовь к Ruby, нельзя не отметить, что популярность асинхронных подходов и микросервисных архитектур отодвинула этот стек на задний план, из-за чего стало сложнее искать специалистов. Именно поэтому в последний раз, когда я руководил разработкой продукта с нуля, я выбрал именно Python-стек — на тот момент так просто было проще набрать команду.

ASP.NET Core и Java Spring Boot

Объединю королей большого энтерпрайза в одну секцию. Традиционно считалось, что .NET- и Java-стеки развиваются более консервативно, поэтому выбирая те же решения на JS и Python можно быть на острие современных трендов разработки.

Однако эта консервативность и покровительство больших корпораций (Microsoft и VMWare) делают эти технологии отличным выбором там, где надежность и производительность продукта важнее скорости разработки и инноваций: в корпоративных системах, банковском финтехе и т. п.

ИASP.NET и Spring Boot обладают огромной экосистемой, позволяющей гибко выбрать архитектуру и при этом использовать готовые наработки, однако кривая обучения для обоих технологий гораздо круче, чем для более популярных JS и Python.

Go и Rust

В большинстве своем оба языка используются в одинаковых целях — создание высокопроизводительных микросервисов с высокими требованиями к скорости вычислений и конкурентности. Go — чуть более простой, Rust — чуть более сложный, но более гибкий. У Go сейчас гораздо шире экосистема для веб-разработки, однако Rust тоже набирает популярность в этом плане.

Использовать Go или Rust как основную технологию на старте проекта следует только в том случае, если производительность вашего решения является одним из уникальных продающих преимуществ продукта (ну или если вашей целью является изучение экосистемы этих технологий и вы делаете пет-проект). Недостаток удобных и развитых инструментов может значительно снизить скорость вывода продукта на рынок.

Однако фраза «переписать на Go» очень часто звучит в командах разработки при росте проектов: благодаря аккуратному микросервисному подходу быстрый компилируемый код является ультимативным инструментом для обеспечения высокой производительности. Особенно это нужно там, где требуется много вычислений или высокая конкурентность: генерация/чтение больших массивов данных, работа с датастримами, нагруженные запросами подсистемы.

При росте аудитории вашего продукта и его сложности, с высокой вероятностью в вашей команде начнут появляться разработчики на Go или Rust, потому что эти компилируемые языки часто являются отличным дополнением к стекам с более развитой веб-экосистемой.

Elixir + Phoenix: немного экзотики

Возможно вы слышали про этот функциональный язык, работающий поверх Erlang-овской виртуальной машины BEAM. На самом деле Elixir — это моя последняя любовь. Созданный для того, чтобы легко создавать отказоустойчивые бэкенды с миллионами параллельных запросов, он обеспечивает производительность на уровне близком к Go и удовольствие от разработки на уровне Ruby.

Возможно вы слышали про этот функциональный язык, работающий поверх Erlang-овской виртуальной машины BEAM. На самом деле Elixir — это моя последняя любовь. Созданный для того, чтобы легко создавать отказоустойчивые бэкенды с миллионами параллельных запросов, он обеспечивает производительность на уровне близком к Go и удовольствие от разработки на уровне Ruby.

Чистые функции, элегантные конструкции, иммутабельность данных, паттерн-мэтчинг — все это позволяет позволяет по-другому взглянуть на разработку вообще, поэтому каждому разработчику я советую хотя бы немного поковыряться в Elixir. Он не очень подходит как первый язык программирования, однако опытным разработчикам может неплохо зайти.

За счет привлечения большого количества поклонников Ruby и Rails сейчас у Elixir довольно обширная экосистема библиотек — и это не считая всех преимуществ Erlang OTP, доступных из коробки: супервизоры, веб-сервер, инструменты для управления потоками и состоянием, телеметрия, встроенное key-value хранилище и даже транзакционная база данных. Все это позволяет выбросить множество компонентов из вашего стека.

Phoenix в свою очередь является самым популярным веб-фреймворком для Elixir, который вобрал в себя многие удачные практики больших фреймворков и перенес все это на функциональную парадигму. Все современные подходы тут легко реализуются: GraphQL в реалтайме, CQRS, Event Sourcing, фронтенд без JavaScript через вебсокеты, распределенные микросервисы — все это почти идеально ложится на этот стек.

Discord, WhatsApp, Slack, Bleacher Report, Pinterest — это лишь небольшая часть компаний, которые публично рассказывали о том, как переход на Elixir значительно сократил издержки и позволил предлагать уникальные функции своим клиентам.

Для большинства стартапов главным аргументом «против» будет малое количество разработчиков на рынке и их относительная дороговизна, но если вы создаете решения для большого количества пользователей, взаимодействующих с вашим приложением в реальном времени, и при этом хотите быстро вывести его на рынок — обратите внимание на Elixir. Для соискателей же это хороший поинт: кажется, что спрос на хороших Elixir-разработчиков превышает предложение на данный момент.

За скобками: Serverless

Говоря про актуальную Backend-разработку, нельзя не упомянуть растущую популярность serverless-подхода. Главным его преимуществом является экономия на инфраструктуре, ведь вы платите облачному провайдеру только за вызовы функций и время их работы, что позволяет компании расходовать столько денег, сколько было использовано фактической вычислительной мощности (а не арендовывать инстансы на постоянной основе).

В serveless можно реализовать REST API или GraphQL, вынести микросервисы, запускаемые по событию, фоновые воркеры и т. п. Спектр применения довольно широк, как и выбор поддерживаемых языков программирования: большинство облачных провайдеров позволяют писать бессерверные функции на Node.js, Python, Go и Java.

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

Клиентская часть: веб-фронтенд и мобильные приложения

В клиентской части тоже есть о чем подумать. Если говорить про веб-клиенты, то одним из самых простых вариантов является подход JAMStack (JS + API +Markup). Он подразумевает предварительную генерацию статических html-страниц на основе данных, полученных из API и html-шаблонов. Это делает подобные сайты супер-быстрыми, ведь не требуется вообще никаких вычислений на сервере в момент запроса — просто возврат уже готовой html-страницы. Однако это больше подходит для корпоративных сайтов, лендингов и простых e-commerce проектов.

С развитием JS-фреймворков большую популярность получил подход SPA (Single Page Application), однако его бездумное применение ведет к большой раздутости кода (и порой к нивелированию преимуществ). Но SPA все еще хороши для приложений, в которых подразумевается большая интерактивность при длительной сессии пользователя: комплексные формы, редактируемые таблицы, сложные личные кабинеты.

Сейчас часто встречается гибридный SSR + SPA подход, когда изначально страница для браузера рендерится на сервере, а реактивная часть происходит уже на клиенте. Это позволяет конечному пользователю быстро получить картинку и не потерять в отзывчивости приложения. А еще есть поверье, что поисковые движки в таком случае будут больше любить ваш сайт.

Если говорить про конкретные фреймворки, то тут есть однозначный лидер в лице React (а также Next.js как SSR-реализации и Gatsby для JAMStack) и пара постоянно догоняющих: Vue.js и Angular. Если нужен зрелый проверенный стек, я выберу React просто исходя из огромного количества разработчиков на рынке и богатого выбора готовых решений в экосистеме.

Из интересных свежих технологий хочу отметить Svelte и его SSR-фреймворк SvelteKit. Он довольно быстро набирает популярность за счет простоты использования при отсутствии компромиссов со стороны скорости работы и размера итогового JS-билда. Если хочется быть на острие, я бы порекомендовал посмотреть в его сторону: судя по отзывам всех знакомых фронтендеров, Svelte действительно очень нравится разработчикам, а это хороший признак долгоживущего фреймворка.

Расскажу про экзотический подход, который я применяю в своих личных пет-проектах. Речь про фронтенд без JS: Blazor отASP.NET, Phoenix Live View на Elixir и Hotwire от Ruby on Rails. Все три решения предлагают отказаться от жирного отдельного приложения для фронтенда, а вместо этого использовать Server Side Rendering с реализацией реактивности через бекенд, используя вебсокеты. Каждый из них делает это по-разному, но в целом это интересная концепция для соло-разработчиков и небольших команд: не нужны JS-разработчики и лишние компоненты в стеке и пайплайнах. Главный недостаток в том, что этот подход плохо масштабируется на другие виды клиентов (например, мобильные приложения).

Кстати о мобильных приложениях. Для большинства современных продуктов недостаточно иметь веб-версию. Выделим современные подходы для мобильных приложений.

  1. Использование PWA (Progressive Web App). По сути, это переиспользование веб-версии в качестве мобильного приложения. Современные PWA могут поддерживать оффлайн-функциональность и минимальные функции мобильных платформ вроде поддержки пуш-уведомлений. Это самый экономный способ выпустить приложение в магазины, но и самый ограниченный с точки зрения функциональности и производительности.

  2. Написание нативных приложений на Swift и Kotlin. Самый дорогой вариант хотя бы потому, что вам нужно иметь в штате две команды, которые делают один и тот же продукт для разных платформ. Однако это лучший подход с точки зрения свободы реализации любого функционала на самих устройствах если вам нужно работать с камерой, геопозицией, On-device ML и другими функциями, которые предоставляют SDK операционных систем.

  3. Кросс-платформенные фреймворки. Тут выбор стоит между React.Native и Flutter. Первый привлекателен тем, что его могут использовать ваши фронтенд-разработчики, а второй — более высокой гибкостью и производительностью. На мой взгляд этот подход является оптимальным решением для большинства продуктов.

  4. No-code. Еще один простой и дешевый вариант для простых приложений. Большинство no-code решений для создания мобильных приложений имеют Rest- или GraphQL-коннекторы, поэтому вполне могут подойти для MVP и прототипирования.

Итоги

Обычно подобные статьи заканчиваются фразами в духе «выбирайте то, что подходит вам». И это, конечно, правильно, но мне все равно всегда хочется послушать субъективное мнение автора. Поэтому сейчас я выскажу свое.

Если прямо сейчас смотреть на рынок разработчиков и развитость экосистем, то для большинства новых продуктов я бы выбирал комбинацию из Python (Django/FastAPI) для бэкендов, React с Next.js для веб-фронтенда и Flutter для мобилок.

А дальше уже действовать от требований. Если приложение подразумевает активное реалтайм-взаимодействие с пользователем — меняем Python на Node.js, Java или даже Elixir. Нужны тяжелые вычисления и высокая производительность — смотрим на Go/Rust илиASP.NET. Нужно удешевить? Выбираем PWA или React.Native, чтобы сэкономить на мобильной команде. А если надо повысить скорость вывода продукта на рынок, то обращаем внимание на Django или Rails.

Материал подготовлен при поддержке редакции ProductStar. Нажмите сюда, если хотите узнать он нас побольше.

ProductStar — онлайн-школа IT профессий, мы входим в состав холдинга РБК. Подписывайтесь на нас в Telegram и знакомьтесь с нашими курсами по программированию от лучших спикеров и менторов на рынке.

© Habrahabr.ru