Node.js vs Ruby on Rails
В отличие от большинства разработчиков, я начинал с баловства с Node.js, и уже после погрузился в Ruby on Rails с помощью восхитительного курса Rails for Zombies и, затем, учебника по Ruby on Rails от Michael Hartl.
Все, что написано далее, есть ненаучное сравнение Node.js и Ruby on Rails.
Начнем!
Node.js — НЕ фреймфорк!
Прежде всего, Node.js — это веб-сервер с низкоуровневой маршрутизацией и возможностями администрирования, написанный на Javascript с целью асинхронности и высокой скорости. И с самого начала этого сравнения, Node.js нуждается в некоторых “друзьях” в виде Express.js и Mongoose (если, конечно, вы выбрали MongoDB свой базой данных). В то время как Rails, напротив, — самый что ни на есть фреймворк, написанный на языке Ruby. Технически, для честного сравнения мы должны были бы говорить тут о Node.js vs Thin или Unicorn, а не Rails, — но ведь мы хотим разрабатывать полный back-end, а не только его моторный отсек.
Ruby — это капризный старик с золотым сердцем.
Теперь, когда избавились от условностей, поговорим о языке. Node.js написан полностью на Javascript, тогда как Rails написан на Ruby. И в одном и во втором есть свои плюсы и минусы. На руку Javascript играет легкость изучения синтаксиса, т.к. многие, наверняка, уже сталкивались с ним во front-end (против присущих Rails
:VARIABLE => “хэш-о-хрень”
def func arg = "необязательности скобок у функций"
VARIABLE do |iterator|
Module::Class декларации классов
деклараций class Subclass < Class
@instance переменных, взятых из Perl
и прочих изысков).
Однако, Ruby может быть более сжатым и не требует леса скобок (coffescript-читатели, не напрягайтесь) для работы всей своей магии. Плюс к этому, Ruby (и Rails) пестреет сверхполезными встроенными методами, окружающими все начиная с дат и заканчивая строками и массивами
10.minutes.ago
“string”.sqeeze
[‘array’,’elements’].include?(‘array’) #true
Да, всего этого можно добиться и на Javascript, но это потребует некоторых знаний и кастомных методов… или что-то вроде _undercore.
100% Javascript — это круто, но уж больно переоценено.
Разобравшись с языками, теперь можно обратить внимание на саму разработку веб-приложений. Node.js привлекает своим асинхронным front-и-back Javascript окружением, тогда как в Rails вам придется иметь дело с SQL, Ruby и Javascript. Хотя, казалось бы, уверенное преимущество — после некоторого изучения обоих, я запишу единообразность языка в категорию “переоцененных преимуществ”. Не так уж и сложно вникнуть в Ruby, прочитав лишь несколько примеров и статей из блогов. Плюс, с Ruby вы можете практически полностью забыть о “лапше из callback'ов”, которая сопровождает Javascript в силу его неблокируемой архитектуры (которую я абсолютно точно признаю плюсом в условиях большого параллелизма). А еще, хоть мне и не хочется этого говорить, иногда неплохо иметь предопределенный синтаксис для пространств имен, классов и модулей.
Rails дает все, что нужно.
Теперь оставим в стороне язык и сопутствующее.
Node.js + Express.js предоставляют роутинг вместе с контроллерами, вью и хэлперами. Однако этот набор инструментов все равно меркнет в сравнении с Rails.
Для аналогии, Rails на фоне Node.js + Express.js — как Muji на фоне American Apparel (две крупные фирмы, продающие одежду и домашние аксессуары — прим. переводчика). И те и другие предоставляют одежду и аксессуары для дома, но шмотки American Apparel выглядят не особо надежно, не всегда удовлетворяют вашим нуждам, стараются выглядеть круто за счет штанов, и часто не смотрятся вместе с другими вещами. С другой стороны, Muji одержимо декорирует все на свете в едином стиле и, на первый взгляд, одной и той же тканью.
Но вернемся к программированию.
Rails идет сразу с выстроенной экосистемой, с полным MVC и с набором полезных функций, испортить поведение которых можно только при критическом косолапии.
Вот пара примеров функций: url_for и image_tag. url_for есть встроенная функция, которая всегда отдаст url данного ей объекта данных (@products, например), а image_tag всегда заберет корректный url картинки из asset pipeline.
Конечно, все это возможно сделать и в Node.js, однако это потребует немалой работы с модулями и хэлперами. Плюс к этому, в Rails вам вообще не нужно беспокоиться о моделях данных. Да, в случае с Node.js может помочь Mongoose, но даже с ним сложно чувствовать полный контроль над данными, какой дает вам
Product.find(params[:id])
доступный повсюду из приложения, модулей, контроллеров и вью в Rails.
Однако, стоит отметить, что все эти фишки имеют и обратную сторону. Я часто понимаю, что просто “угадал” верный путь сделать то или иное, и почти всегда упускаю наилучший путь. А также, когда что-либо ломается, бывает довольно сложно определить причину поломки из-за хитрых специальных имен переменных (например, склеив название действия + название контроллера + "_path", можно магическим образом получить хэлпер new_product_path, возвращающий актуальный путь к необходимому действию).
С Node.js же вы видите лишь то, что написали сами — искажения минимальны.
Множество людей делают и улучшают модули для Rails.
Далее: экосистема. Несмотря на то, что у Node.js был прекрасный старт с NPM, на большинстве даже самых популярных пакетов для различных нужд еще не осела пыль, а количество конкурентов уже бьет рекорды. В итоге я часто ощущаю себя как будто пытающимся склеить разбитую вазу суперклеем.
На стороне Rails же — один из наиболее крепких свободных репозиториев библиотек и инструментов. Мне также весьма нравится The Ruby Toolbox, показывающий относительную популярность инструментов, разбивая их по функционалу. Плюс ко всему, как я уже говорил, множество модулей, которые в Node приходится набирать вручную, в Rails идут из коробки. Такие вещи, как связь с БД, профайлинг, кэширование, миграции, модели данных, pipelines, роутинг, консольные команды, тестирование и прочее… Даже favicon’ка уже на месте! Конечно, все это тривиально, но ведь все необходимо, и было бы круто не видеть всех этих сообщений о конфликтах Node.js модулей, которые отчего-то отказываются общаться друг с другом до полудня.
Над всем этим — огромное количество учебников и примеров на Rails, куда больше, чем есть на Node.js. Один только Railscasts с его 300+ видео. Но стоит иметь в виду, что Rails меняется быстро, и множество учебников уже потеряли актуальность, а иные задачи получили свои решения уже после публикации тех или иных статей с обходом. В результате, стало разумно использовать гугловские селекторы < 1 year old
для поиска ответов на вопросы про Rails, и начинать сей поиск с Rails Guides.
В Rails включен jet-pack. По умолчанию.
Наконец, предположим что у вас есть одинаковые фреймворки, БД, модули настроены и все отлично. Node.js требует куда больше времени, чтобы просто все написать и все собрать (снова из-за несогласованности сторонних плагинов и отсутствия жесткой структуры). В Rails, чтобы собрать полный RESTful интерфейс, достаточно всего одной команды
rails generate scaffold Post name:string title:string content:text
и нужные контроллер, вью и модель будут ждать на своих местах.
Часто это занимает 1 минуту против 1 часа (помноженного на количество сущностей БД). Это не такая сложная работа, но довольно уязвимая к опечаткам, да и просто масса информации, которую необходимо помнить. Я не всегда пользуюсь Rails scaffolds, но для простых прототипов более быструю альтернативу придумать сложно.
В заключение…
Node.js — это прекрасный набор инструментов, модный, быстро растущий, высокопроизводительный (что спорно), легко осваиваемый и выигрывающий у большинства прочих инструментов веб-разработчика. Однако, он все равно остается талантливым звездой-старшеклассником против Олимпийского Бога в лице Rails. Не в обиду Node.js, но кого бы вабрали вы? Если можете преодолеть неудосбтва, связанные с изучением Ruby — выбор пока очевиден. Запомните: лучший инструмент — это тот, который позволит вам сделать работу лучше и быстрее.
P.S. От переводчика:
Конечно, более корректно сравнивать Rails не с чистым Node, а с каким-либо MVC фреймворком на его основе. Например, Sails.js. Однако, эта статья несет некий объем полезной информации для начинающего web-разработчика (коим был я), так что позволю себе метафорический комментарий.
- Rails снабжен огромным количеством функций и библиотек, которые сделают ваше рабочее место надежным и комфортным чоппером в мотомире веб-разработки.
- Node развивается чудовищными шагами, предоставляя разработчику чуткий к поломкам, но интересный и модный спортбайк.
Исходя из личного опыта, Node.js + Sails.js дал мне более легкую альтернативу Rails для небольших проектов — и это здорово. Но надежность и крепкость RoR в условии разработки серьезного веб-приложения они пока что заменить не в силах, хотя и цепляют душу back-end-developer'а.
Всем прочитавшим спасибо!
Автор: sca