JavaScript-приложение, или зачем нам Razor в ASP.NET MVC?

    image

    Не думал, что напишу это, но JavaScript победил. Мы перестали использовать Razor для создания веб-приложений. Вместо этого реализуем front-end в отдельном проекте на JavaScript-фреймворках. От ASP.NET остался только WebAPI и «движок», на котором мы пишем бизнес-логику и API для пользовательского интерфейса.



    Вселенная JavaScript и CSS



    Последнее время мы наблюдаем взрывное развитие веб-технологий. Появились полноценные IDE для работы с HTML/CSS/JavaScript, проекты типа Grunt и сотни JavaScript-фреймворков. Инфраструктура для создания front-end'а стала взрослой.

    Давайте посмотрим на статистику Github. Я нашел два источника статистики по языкам программирования, в обоих JavaScript стоит на первом месте.

    В статье Language Trends on GitHub посчитали с помощью Linguist, что JavaScript на первом месте на GitHub по популярности, среди языков программирования:

    image

    GitHut показывает аналогичную ситуацию:

    image

    Теперь я понимаю откуда каждую неделю появляются новые JavaScript-фреймворки. Могу себе представить трудозатраты сообщества JavaScript-программистов, которые поставили JavaScript на первое место на github.

    Миф о кроссфункциональности



    Мы отказываемся верить во всемогущих full-stack web-разработчиков. Full-stack означает, что программист разбирается и в .NET, и в JavaScript/CSS.

    Что значит разбираться в этих двух мирах? Это значит знать тонкости работы с браузерами, знать и практиковаться с новыми JavaScript-фреймворками, и одновременно с этим знать о новых фишках в C#, изменениях в платформе .NET, следить за новыми версиями ASP.NET MVC и новым базами данных. Такого всезнающего full-stack web-разработчика я последний раз видел… никогда. Охватить и стать экспертом в этих двух областях не под силу смертному. Я не говорю о людях с железным стержнем и безграничным запасом свободного времени, речь об обычных людях типа меня.

    Если вы спросите меня, знаю ли я JavaScript и CSS? Я отвечу, что знаю. Но знаю ли я эти технологии достаточно, чтобы создать качественное решение на front-end? Нет, моих знаний недостаточно, я знаю эти технологии поверхностно по сравнению, например, с front-end разработчиками нашей компании.

    Я пришел к выводу, что сложный проект не создать силами full-stack разработчиков . Если речь о сложном UI и сложном back-end, то специализация необходима. Доверять full-stack разработчикам проекты сложнее, чем натягивание дизайна на CMS, настройки интерфейса в SharePoint или кастомизации Bootstrap — губительно для проекта.

    История из соседней компании. Lead .NET разработчик усмотрел проблемы на front-end. Он решил, что у UI-проекта неправильная архитектура и технический долг, поэтому он пошел наводить там порядок. В итоге стало еще хуже, чем было, потому что JavaScript-приложение он создавать не умел.

    Я думаю похожая ситуация могла бы произойти, если бы JavaScript-разработчик полез в C#. Разница в том, что .NET разработчики считают, что смогут корректно поправить JavaScript/CSS, а front-end разработчики знают, что им в C# лучше не залезать и они не лезут.


    Схема взаимодействия



    На старте работы мы делаем два проекта. Первый проект традиционный — ASP.NET Web API приложение в Visual Studio, второй проект в Webstorm. Оба проекта лежат в одном репозитории, хотя это не обязательно.

    image

    Front-end разработчики согласуют с back-end разработчиками API, через которое происходит взаимодействие двух приложений.

    Процесс работы



    Мы создаем проектные команды, поэтому разработчики, QA и другие члены команды входят в состав единой команды проекта. В том числе front-end и back-end разработчики входят в эту команду. Единая команда работает с Impact Mapping, Customer Journey Mapping, User Story Mapping, которые появляются во время процесса создания ПО:

    image

    Видно, что с точки зрения процесса создания ПО, мы никак не разделяем front-end и back-end части. Это осознанный шаг, который помогает делать поставку бизнес-ценности.

    Плюсы и минусы



    В разделении front-end и back-end на два проекта я нахожу и плюсы и минусы:
    • Плюсы
      1. Front-end и back-end проекты слабо связаны. Становится возможно развиваться эти проекты параллельно или отдельно друг от друга.
      2. У вас случалось, что кроме веб-интерфейса, вас просят создать API к Android-приложению? У нас заказчики просили об этом и не раз. Если вы изначально создаете API, документируете API, то подключение новых клиентов к нему не составляет труда.
      3. Выкладка  front-end и back-end частей теперь может происходить независимо. Вам не придется перезаливать монолитное ASP.NET MVC приложение из-за изменений в JavaScript/CSS или разметки.
      4. Чем сложнее проект, тем сложнее управлять монолитным ASP.NET MVC приложением. Если разнести единое приложение на два проекта, как показано в статье, то развивать два небольших проекта проще.
      5. В монолитном ASP.NET MVC приложение цена ошибки это весь проект. В раздельных проектах цена ошибки это части системы.

    • Минусы
      1. Нужны сильные front-end разработчики, которые могут и не понадобится, если full-stack разработчики создают back и front.
      2. Следствие из предыдущего пункта — нужно больше людей в проект.
      3. Инфраструктура сложнее, усложняется процесс сборки релиза.
      4. Дополнительно время тратиться на согласование API между двумя проектами.
      5. Изменения в бизнес-логике часто затрагивают оба проекта.



    Выбор подхода



    Мы выбираем ASP.NET MVC приложение и рендер HTML через Razor, если используем CMS или пишем небольшой проект без сложной бизнес-логики. Например, так сделан сайт компании ByndyuSoft. Мы выбираем front-end в виде JavaScript-приложения во всех остальных случаях.
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 22
    • +6
      Понятно, что нет необходимости использовать Razor если вы используете Web API, но если вы используете ASP.net MVC, то Razor просто шикарен и я не встречал шаблонизатор лучше.
      • 0
        Речь скорее о том, что мы ушли от шаблонизатора Razor и перешли к JS-шаблонизаторам в отдельном JS-приложении. Если мы создаем ASP.NET MVC приложение и рендерим с помощью него HTML, то используем Razor.
        • 0
          Я так и понял.
          • 0
            Не думал, что напишу это, но JavaScript победил. Мы перестали использовать Razor для создания веб-приложений.

            Исходя из названия статьи и первых её фраз можно было подумать, что вы собираетесь утверждать о ненужности server-side rendering как такового :)
            • 0
              Надеюсь продолжение статьи развеивает это впечатление.
      • +1
        У, такими темпами скоро дойдете до того, что бекэнд будет не на ASP.NET ))
      • +1
        А БД какую используете или собираетесь использовать, если будете еще на Linux запускать? И ваша команда вроде практиковала CQRS подход, не отказались еще?
        • 0
          Из БД у нас больше всего используются MSSQL, PosgtreSQL, MongoDB, Sphinx. Три последние мы хостим на Linux.

          Да, мы практикуем CQRS. Нам нравится, пока альтернативы не нашли :)
        • +7
          А не могли бы вы рассказать, как в проектах с подобной архитектурой реализуется валидация правил, локализация и подобные вещи, имеющие отношение как к UI, так и к бизнес-логике? В каком виде приходят сообщения об ошибках?
          • 0
            Подпишусь на этот вопрос.
            • +3
              Сергей, вопросы понятные и актуальные. Я собираю информацию по нашим проектам, чтобы рассказать вам общие выводы.
              • 0
                Вот да, тоже об этом хотел спросить. По мне, так локализацию лучше как раз отдать рейзору и бэкэнду, чем тому же ангуляру.
                • 0
                  > локализацию лучше как раз отдать рейзору и бэкэнду, чем тому же ангуляру

                  Какая разница где писать переводы? Механизмы выбора перевода одинаковые. Из текста по ключу выбирается перевод в зависимости от локали.
                • 0
                  Локализацию можно использовать из *.resx-файлов. Для этого потребуется сгенерировать часть js-кода со стороны .NET и отдать отдельным файлом. Для большинства проектов оверхед на один запрос не значительный, работает хорошо. Файл создается только один раз при старте приложения или встраивается в билд-процесс.

                  Для валидации так-же можно генерировать js-код на сервере, используя DataAnnotations. В случае с кастомной валидацией, которая нужно описывать в виде императивного кода — ничего не поделаешь — нужно дублировать код.

                  Если хочется совсем упороться, то можно посмотреть в сторону Roslyn и конвертировать C#-код валидации в JS. Есть вот такой пример конвертирования C# в С++ от mezastel. Учитывая, что в ES6 есть поддержка лямбд подобная задача может быть интересна с исследовательской точки зрения. В коммерческой разработке применять такие решения скорее всего дороговато.
                  • +1
                    > реализуется валидация правил

                    Валидация реализуется на front-end и back-end приложениях.

                    Часть валидаций относятся только к front-end, например, пока поле не заполнено не нажимать кнопку.

                    Часть валидаций одинаковые для front и back, например, валидация формата телефона или бизнес-правило не добавлять в корзину Х, если там уже Y. В этом случае логика реализуется и на front и на back.

                    Часть валидаций только на back, например, является ли логин уникальным.

                    По сути ничего не изменилось со времен, когда мы использовали только ASP.NET MVC. Единственная разница это отсутствие атрибутов валидации, которые можно было вешать на модель. Но это почти не заметно в работе, т.к. эти атрибуты покрывают обычно самую простую валидацию: пустные поля, маска для поля и т.п.

                    > локализация

                    Локализация front-end делается стандартными средствами. Можно для примера посмотреть как сделана локализация jQuery UI. Есть файл с переводами, есть механизмы выбора переводов из этого файла. Очень похоже на то, как сделаны переводы через ресурсы в .NET

                    > В каком виде приходят сообщения об ошибках?

                    Они приходят ответом на Ajax-запрос, а формат такой, какой будет согласован. Обычно это просто JSON.
                    • +1
                      Спасибо за развёрнутый ответ. Поясню, моя цель, в общих чертах, состоит в уменьшении связности между backend и frontend для параллельной разработки. Есть общее соглашение о формате данных, но в частностях хотелось бы оставить некоторую свободу — например, чтобы изменение правил валидации не влекло за собой необходимость одновременной модификации frontend. Пока я склоняюсь к публикации неких метаданных с backend, подобно IClientValidatable-правилам. Сначала я хотел избежать необходимости локализации и клиента, и API, но, похоже, это мечты :)

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.