Node.js vs Ruby on Rails

Original author: Will Nathan
  • Translation

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'а.
Всем прочитавшим спасибо!
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 33

    +10
    Зачем переводить такой бред, похоже автор опуса не подозревает что под капотом рельс находится язык ruby.
    RoR же является набором библиотек, так что все ссылки на то, что в ноде нужно что-то доставлять — вызывает улыбку.

    Ну и у ноды киллер фича — асинхронность. Так что учить нужно обязательно, без разницы какой язык и фреймворк у вас основные. Это довольно разные молотки.
      +2
      Ну и у ноды киллер фича — асинхронность. Так что учить нужно обязательно, без разницы какой язык и фреймворк у вас основные.

      В ноде это все-таки через колбэки, что не очень приятно. В этом плане гораздо приятнее смотрится реализация на Tornado/Python
        +1
        Есть библиотеки вроде asynс, которые позволяют писать нормальный код даже без кофескриптов. Читается лучше, чем магии рельс.
        При чём это так удачно, что подобное апи я сейчас реализую подобным образом и для php библиотек.

        p.s. пишу на обоих сабжах, но они они дополнительные и знание не глубокие, но проблем не испытываю ни с тем, ни с другим.
          +1
          не холивара ради (сам использую async), но Вам не кажется, что использовать стороннюю библиотеку для возможности писать нормальный код — это как-то не очень?
            +2
            В node.js это нормальная практика. Так получилось, что стандартная библиотека не очень богатая. Всякие request и lodash сильно упрощают жизнь.
              0
              Поддерживаю async и только async, для контроля асинхронного потока, методы mapSeries, parallel и waterfall просто необходимы. С coffeescript' ом все будет еще более читабельнее для человека, который знаком с node.js и async.
              0
              Я думаю это было неизбежно и кто-нибудь все-равно написал бы обертку под это дело.
                0
                Чёрт его знает, но в каком языке это не так. В мире ruby — rails, node.js — expressjs, javascript — jquery, C# — .net, java — spring, php — laravel…

                Я воспринимаю это нормально, мир не идеален.
              0
              В EcmaScript 6 появились generators, с которыми станет приятно. developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
                +1
                И даже УЖЕ стало прияно. node v.11.xx --harmony вместе с koajs или просто co и все вообще шикарно. А ещё в es7 будут async, await как в .NET.
                +1
                В этом плане гораздо приятнее смотрится реализация на Tornado/Python

                Кроме этого, в Python ещё есть gevent и свежий asyncio. Ассортимент.
                +1
                ну а кто запрещает использовать EventMachine и получить асинхронность и reactor-паттерн на руби?
                +7
                Node.js написан полностью на Javascript, тогда как Rails написан на Ruby.

                Сравнение теплого и мягкого.
                  0
                  joyent/node на плюсах основная часть, причем)
                    –3
                    Правда?
                    image
                      +2
                      Статистика выглядит так, потому что в свое время из репозитория вынесли несколько элементов в отдельные зависимости. В первую очередь, это Libuv и HTTP Parser.
                        +4
                        Вообще странно Гитхаб считает статистику по языкам в проекте. Вот что выдал мне Cloc:

                        --------------------------------------------------------------------------------
                        Language                      files          blank        comment           code
                        --------------------------------------------------------------------------------
                        C++                             454          79233          58793         663096
                        C                              1267          52937          84691         354145
                        Javascript                     3887          53394         106568         278543
                        C/C++ Header                    805          44693          55454         185470
                        Assembly                        131          12115           2284         155225
                        Perl                            173           8884           8237          70352
                        Python                          174          10047          17745          40322
                        make                             98           2140            854          15797
                        HTML                            130           3386             58          12647
                        Lua                              25           1040           1355           9264
                        Bourne Shell                    108           1247           1383           5932
                        DOS Batch                        42            510            143           1807
                        m4                                2            515              0           1640
                        CSS                              10            163             89           1523
                        D                                 4            102            316            712
                        PHP                               5            133            473            698
                        Lisp                              5             56            107            489
                        Bourne Again Shell                6             12              6             85
                        Ruby                              1             15              4             76
                        YAML                              9              9              0             46
                        XML                               4              2              0             20
                        awk                               1              1              2             10
                        --------------------------------------------------------------------------------
                        SUM:                           7341         270634         338562        1797899
                        --------------------------------------------------------------------------------
                        


                        Интересно, что если выкинуть зависимости и папку /tools, то статистика будет совсем другой: чисто в самом ноде намного больше JS:

                        --------------------------------------------------------------------------------
                        Language                      files          blank        comment           code
                        --------------------------------------------------------------------------------
                        Javascript                     1013          15056          25471          60398
                        C++                              42           4995           1759          17025
                        C/C++ Header                     46           1197           1412           8153
                        


                        А если сиключить тесты, то получим:

                        --------------------------------------------------------------------------------
                        Language                      files          blank        comment           code
                        --------------------------------------------------------------------------------
                        Javascript                      104           4940           4100          19838
                        C++                              37           4885           1738          16678
                        C/C++ Header                     46           1197           1412           8153
                        


                        Получается, что 2/3 JS-кода в Node.js — это тесты.
                    –1
                    Это точно. Не судите строго, это всего лишь перевод.
                    JS — особенный язык в плане своей идеологии. Но и Ruby довольно особенный. Имхо, в плане лояльности к разработчику Ruby выше всяких похвал.
                      +1
                      Да суть не в том даже. Просто node.js и rails это вобще разные вещи. С таким же успехлм можно сравнить PHP с JQuery.
                        +5
                        Ну знаете, есть такая плоскость сравнения, когда решают, на чем писать новый проект. Говорят «над Java, или на .NET, или на Python, или на Rails, или на Node.js, или еще на чем-то». Да, можно до хрипоты спорить, что Java и Python — языки, .NET и Node.js — среды выполнения, а Ruby on Rails — фреймворк. Все равно в момент, когда обсуждают, на чем писать, все понимают, что именно имеется в виду.

                        Сравнивают экосистемы в целом: Rails vs Node — это

                        — Ruby + Rails + Bundler + Rubygems +…

                        против

                        — JavaScript + Node.js + npm +…
                          0
                          Ну я не понимаю как можно сравнить среду и фреймворк. Если уж сравнивать, то хотя бы Express и Rails. Наверное самое близкое что можно сравнить это Sails и Rails. Просто когда сравнивают такие вещи сразу кажется, что у автора недостаток понимания предметной области. (К переводу претензий нет).
                            0
                            Как я понимаю сравниваются соотношения результата с потраченными ресурсами.
                    +5
                    тогда как в Rails вам придется иметь дело с SQL, Ruby и Javascript


                    На счет SQL — сильно спорно. Его приходится использовать только в исключительных случаях. Т.е. очень редко.
                      +1
                      Кстати, да! Пишу уже несколько лет на Рельсах и случаи, когда приходилось писать прямой SQL запрос можно пересчитать буквально по пальцам. Что, как я считаю, очень и очень замечательно!
                        0
                        Писать чистый SQL в рельсах, это вообще-то признаки плохого тона. Для всего кастомного нужно использовать Arel
                        0
                        Я бы не стал писать большой сайт на node.js. Слишком многое, что уже есть в рельсах придется писать самому. На мой взгляд, даже десятикратный выиграш в производительности не стоит того времени, которое придется потратить на разработку. С другой же стороны, для API node.js в самый раз, хотя тут конкурентом скорее будет Sinatra.
                        Кстати, о асинхронности. В типичном веб сайтике единственное место, которое, как говорит Ryan Dahl, слишком медленное, чтобы на него ждать — это база данных. Все остальное и так уже в памяти. Может, если вы не будете ходить в базу десятки раз на каждый запрос, потеря производительности будет не такая уж и большая?
                          0
                          Прежде всего, Node.js — это веб-сервер с низкоуровневой маршрутизацией и возможностями администрирования, написанный на Javascript с целью асинхронности и высокой скорости.

                          Почему Node.js — это веб-сервер, почемe C/C++ не веб-сервер, а Node.js веб-сервер. В одном из моих проектов она вообще веб клиент, а ещё в одном она применяется для парсинга бинарных файлов и записи распарсенного в базу. Да на к ней можно подключить модуль веб-сервера, но зачем пытаться загнать реализацию JavaScript в рамки веба?
                            0
                            Вы правы: node.js это не веб сервер, а набор библиотек для JavaScript, хотя чаще всего используется как раз для всяких действий по HTTP; автор node.js, например, немного повёрнут на HTTP, и поэтому нам приходится обрабатывать чанки ответов по мере их поступления вместо более привычного и удобного целого объекта.
                            Но вы и неправы: это не реализация JavaScript. Реализация называется V8 и пишется совсем другими людьми.
                            –2
                            > Product.find(params[:id])
                            > доступный повсюду из приложения, модулей, контроллеров и вью в Rails.

                            Но это же хрестоматийный буллшит!
                              0
                              Нода, нода. Асинхронность. Ужас какой. Все умрем. Traceur пользуйте уже наконец на бэкэнде, динозавры.

                              app.post('/callback', function (req, res) {
                                      runGenerator(function* (resume) {
                                          var [, [cellReflection]] = yield Cell.getRandomFree(resume),
                                              [, [cell]] = yield Cell.find(cellReflection._id).exec(resume),
                                              user = new User(req.params.user);
                                          yield user.save(resume);
                                          var [, lastBiggestId] = yield Cell.findBiggestId(resume);
                                          cell.user = user;
                                          cell.index = lastBiggestId + 1;
                                          yield cell.save(resume);
                                          res.json(cell);
                                      });
                                  });
                              
                                +1
                                Зачем traceur? И без него хорошо.
                                  0
                                  в 0.11 часть пакетов не работает, увы(
                                0
                                Лучше уж тогда сравнивать, например, Meteor и RoR, было бы честнее.

                                Мне нравятся и рельсы, и метеор, на обоих пишу, если что (-:

                                Only users with full accounts can post comments. Log in, please.