веб приложение и веб портал
Чем отличаются веб-сервис, веб-приложение и сайт
Серьёзный программист скажет, что это части одной системы, а не виды продуктов. А потом выдаст: «Делаем не сайт, а веб-приложение, — или, — Сайт готов, но нужно ещё подключить веб-сервисы». Как это понимать?
Только показываем или взаимодействуем?
Сравним блинную в торговом центре и федеральную сеть доставки пиццы.
Блинной хватает онлайн-визитки с указанием, какие блины она жарит, где находится. Можете анонсировать там скидки и мастер-классы, размещать срочные объявления: «Сегодня закрыты. Нет воды».
Пиццерия принимает заказы через сайт и мобильное приложение. С клиентами общается робот (чат-бот). У поваров и курьеров — свои приложения, чтобы получать задачи и фиксировать ход работ. Простеньким сайтом тут не обойтись: нужен целый комплекс программ.
Как работает веб-приложение
Повар раскатал тесто, выложил начинку, отправил пиццу в печь, упаковал в коробку для доставки. Так вот, коробка — это сайт, печь — веб-сервис, а повар — веб-приложение. Пицца, коробка, печь, повар — это не отдельные услуги, а часть единого процесса.
Перейдём от метафоры к реальности.
«Реализуем архитектуру “клиент-сервер”», — объявили разработчики. Что это значит: клиент только «просит» сервер поработать и выдать результат. Бизнес-процесс выполняется на сервере, а не на устройстве клиента. Веб-приложение — та часть кода на сервере, которая выполняет бизнес-процессы.
Веб-сервис — ещё более техническое понятие. Если веб-приложение хоть как-то касается клиента, то веб-сервис работает не с клиентом, а с другими приложениями и сервисами. Это код для другого кода.
Поясним на примере.
Заказчик пиццы при оформлении вводит адрес, контакты, номер карты. На сервер отправляется команда «Оформляй!» Сервер, а точнее, приложение на сервере, вычисляет стоимость доставки, применяет скидки, начисляет бонусы, записывает заказ в базу, уведомляет кухню и курьера, связывается с банком для оплаты, создаёт проводку для бухгалтерии. Проделав всё это, сервер отчитывается: «Заказ оформлен!» Заказчик видит уведомление.
Где тут веб-сервис? Там, где пиццерия связывается с банком, чтобы снять деньги со счёта плательщика. Он не видит, как сервер опрашивает банк: хватает ли денег на карте, правильно ли введены данные, не состоит ли карта в чёрном списке. С банком общается вспомогательный код — «веб-сервис». Ещё есть второй веб-сервис, для сбора метрик, и третий, для имейл-рассылок.
По сравнению с этим, на сайте блинной обрабатывать нечего: надо просто показать статичный текст и изображения. Пара незамысловатых страничек безо всяких приложений и сервисов.
К чему готовиться
Веб-приложение помогает компании расти благодаря тому, что:
Но вместе с тем оно приносит новые трудности:
Коротко о главном
В обиходе под сайтом понимают справочную: лендинг, портфолио, визитку. Пользователь ничего не делает, а только читает, что написано.
Под веб-приложением имеют в виду нечто более сложное: интернет-магазин, онлайн-банк, электронные госуслуги. Там есть взаимодействие с клиентом.
Говоря «мы разрабатываем веб-сервис», подразумевают, что пишут вспомогательный код. Для сбора метрик, например.
Технически приложение и сервис — не виды продуктов, а детали пазла. Малый оффлайн-бизнес обойдётся без них, средний и крупный онлайн-бизнес — нет. Пиццерия с онлайн-заказами никак не может быть простым сайтом.
Website и Web Application: в чем разница
Владельцы онлайн бизнеса могут столкнуться с проблемой: выбрать ли им веб приложение или вебсайт для дальнейшей деятельности. В то же время, сфера онлайн торговли стремительно растет. Как сообщает портал Statista, в 2022 году общий объём онлайн продаж достигнет 638 051 миллионов долларов США.
Для большинства людей нет разницы между вебсайтом и веб приложением. Но для тех, кто хочет создать свой онлайн бизнес, так же, как и для команды разработчиков, разница есть, и она непосредственно влияет на то, какими знаниями должен обладать разработчик.
В этой статье мы расскажем вам о:
Есть идеи по поводу вашего проекта?
Веб приложение или вебсайт
На самом деле, конечный потребитель даже не задумывается, что он использует, вебсайт или веб приложение. Пользователь просто вводит URL в поисковой строке. Но смысл в том, что «сайт» должен делать то, что предполагает пользователь.
В то же время для команды e-commerce разработчиков между созданием сайта и веб приложения есть существенная разница. Помните это, когда у вас возникнет вопрос, что лучше создавать для онлайн бизнеса. Но, чтобы сделать правильный выбор для вашей компании, стоит учесть ту информацию, о которой мы расскажем далее в статье.
Основные функции вебсайта
В основном сайты характеризуются информативностью. Как пример можно привести блоги или новостные сайты. Основная цель – дать посетителям необходимую информацию.
Выше вы можете видеть один из сайтов, разработанный командой Dinarys.
В большинстве случаев пользователи не имеют или имеют ограниченное взаимодействие с сайтом. Под «ограниченным» мы имеем в виду форму подписки и поиск по сайту. Поэтому, стоит ли вам ограничиться созданием сайта для вашей бизнес модели онлайн торговли?
Если вы хотите разместить немного информации о вашей компании, включая описание, ближайшие мероприятия и контактную информацию, вы можете выбрать вебсайт.
Основные функции веб приложения
В отличие от вебсайтов, веб приложения созданы для взаимодействия с пользователями. Веб приложения тоже могут быть информативными, но они могут также и обрабатывать информацию, полученную от пользователей.
Как пример веб приложения, мы можем привести системы онлайн банкинга. Вы можете видеть информацию и даже совершать действия, основанные на введенных данных.
Полезные веб приложения улучшают нашу жизнь. Как пример, мы можем рассмотреть Adobe Color CC.
Веб приложение vs вебсайт: основные различия
Чтобы быть более точными, мы решили рассказать вам об основных различиях вебсайтов и веб приложений.
Интерактивность
Первое отличие – это разные степени взаимодействия со страницей. В то время, как вебсайты содержат тексты и визуальный контент, с которым пользователь не может взаимодействовать, веб приложения дают пользователю возможность не только читать, но и манипулировать информацией на странице. Это можно рассмотреть в виде диалога. Пользователь взаимодействует с интерфейсом сайта и получает ответ. Под «ответом» мы подразумеваем электронную оплату, онлайн чат, загрузку документов и др.
Онлайн магазин, который позволяет пользователям покупать товары, совершать поиск через каталог, может быть веб приложением. Еще один интересный пример – это социальные сети. Они также включают в себя функции блога, чаты, контент на выбор пользователя и возможности делиться этим контентом.
Сегодня большинство вебсайтов обладают интерактивностью. Потому что пользователям это нравится. Для этого, владельцы сайтов добавляют небольшие веб приложения на свой сайт.
Еще, на сайтах некоторых ресторанов есть виджет Google Maps, который помогает пользователям найти дорогу к ресторану. В то же время, большинство сайтов скорее информативные, чем интерактивные. Таким образом, посетители сайтов больше увлечены просмотром, чтением информации или прослушивание аудиофайлов. А посетители веб приложений направлены на взаимодействие с пользователем.
Интеграция
Интеграция – это процесс объединения простых компонентов в один сложный. Разработчики могут интегрировать веб приложения и сайты с программами, включая ERP, CRM. Однако в большинстве случаев интеграция происходит именно с веб приложениями. Почему? Потому что их сложным функциям зачастую требуется дополнительная информация от сторонних систем. Самый популярный вид интеграции в e-commerce – это интеграция веб приложения с системой управления взаимоотношениями с клиентами (СRM). Это помогает хранить данные о покупателях, информацию о заказах и улучшает работу команды продаж. Благодаря интеграции, информация о пользователях веб приложений автоматически собирается и сохраняется в CRM системе. Подобная интеграция позволяет команде отдела продаж узнавать больше о поведении клиентов, их предпочтениях при покупке товаров и эффективнее работать с негативными отзывами. Это очень выгодно для владельцев онлайн бизнеса, поскольку все изменения в информации о клиенте автоматически отображаются в CRM. Подобный способ взаимодействия с информацией о клиентах может принести увеличение в продажах и улучшение процессов работы онлайн магазина.
Авторизация
Этот процесс включает в себя ввод пользовательских данных для получения доступа к вебсайту или системе. Эта функция важна для систем, которым требуется любая личная информация о клиенте. Более того, на этом этапе, уделите особое внимание безопасности. Важно минимизировать возможность доступа к личным данным пользователей посторонним лицам.
А отличие от сайтов, веб приложениям чаше требуется авторизация. Почему? Потому что они предоставляют пользователям больше возможностей, чем вебсайты. Например, при использовании социальных сетей, системы предупреждают вас о слабых паролях. А игнорирование подобных сообщений может привести к тому, что хакеры могут взломать ваш аккаунт.
Большинство информационных сайтов используют авторизацию. В некоторых случаях это используется для того, чтобы дать больше возможностей, которые недоступны неавторизированным пользователям. Если незарегистрированные пользователи могут только просматривать статьи, зарегистрированные пользователи могут оставлять комментарии, делиться статьями в социальных сетях и т.д. Это также отличное решение для блокирования спама. Таким образом, авторизация необходима как для вебсайтов, так и для веб приложений. В то же время, это нужно веб приложениям в целях безопасности.
Успешная комбинация
При создании информационных порталов или разработки онлайн магазинов, вы можете использовать преимущества как вебсайтов, так и веб приложений. Давайте объясним. Изначально сайты на праформе WordPress должны отображать информацию посетителям. Поэтому мы можем сказать, что это – сайт. В то же время, back-end такого сайта оснащен CRM системой, которая достаточно гибкая. Поэтому у подобного сайта есть и функции веб приложения.
Мы можем сказать, что большинство вебсайтов сочетают в себе функции веб приложения и веб сайта.
Пример сайта, разработанного командой Dinarys, который сочетает функции сайта и веб приложения.
Команда разработчиков
При выборе между веб приложением и веб сайтом стоит в первую очередь отталкиваться от потребностей вашего бизнеса. Если вашей копании нужен вебсайт, то вы можете нанять небольшую аутсорсинговую компанию, специализирующая на e-commerce. Такие команды без проблем могут справиться с разработкой вебсайта и индивидуальным дизайном, где вы сможете разместить информацию о вашей компании. Но если вам необходимо добавить кастомный модуль на сайт или разработать его с нуля, вам нужно поискать команду, специализирующуюся на разработке веб приложений. Более того, при поиске такой команды, обратите внимание на готовые веб приложения, которые должны быть у команды в портфолио.
Выводы
Если вам нужно сделать выбор между веб приложением и сайтом для e-commerce бизнеса, то сделать выбор, на первый взгляд, достаточно сложно. Поскольку вебсайты и веб приложения работают в браузерах, им необходимо подключение к интернету, у них есть back-end и front-end. Более того, они могут быть написаны на одном языке программирования. Им присуща интеграция, интерактивность и авторизация пользователей.
Однако команда Dinarys спешит обратить внимание, что разница между ними все же есть. Более того, если вы ищите решение для вашего онлайн бизнеса, вам важно понимать эту разницу. Также стоит помнить, что в большинстве случаев владельцы онлайн бизнеса нанимают команду Dinarys для создания онлайн магазинов на специальных платформах, поэтому вам также стоит рассмотреть и этот вариант. Мы надеемся, что эта статья была вам полезна и расставила все точки над «I» какие решение выбрать и какую команду нанять для процесса разработки.
Чем Dinarys может помочь вашему E-commerce бизнесу?
Команда предоставляет такие услуги, как:
Если вы заинтересованы в этих услугах или вам нужна консультация для вашего e-commerce решения, заполните форму по ссылке и команда вскоре свяжется с вами!
Вы можете поделиться этой статьей
Доверьте поиск решения профессионалам
Наши сертифицированные специалисты знают, как воплотить вашу идею в реальность.
Как работают веб-приложения
1. Чем веб-приложения отличаются от сайтов
Для меня сайт это в первую очередь что-то информационное и статичное: визитка компании, сайт рецептов, городской портал или вики. Набор подготовленных заранее HTML-файлов, которые лежат на удаленном сервере и отдаются браузеру по запросу.
Сайты содержат различную статику, которая как и HTML-файл не генерируется на лету. Чаще всего это картинки, CSS-файлы, JS-скрипты, но могут быть и любые другие файлы: mp3, mov, csv, pdf.
Блоги, визитки с формой для контакта, лендинги с кучей эффектов я тоже отношу для простоты к сайтам. Хотя в отличие от совсем статических сайтов, они уже включают в себя какую-то бизнес-логику.
А веб-приложение — это что-то технически более сложное. Тут HTML-страницы генерируются на лету в зависимости от запроса пользователя. Почтовые клиенты, соцсети, поисковики, интернет-магазины, онлайн-программы для бизнеса, это все веб-приложения.
2. Какие бывают веб-приложения
Веб-приложения можно разделить на несколько типов, в зависимости от разных сочетаний его основных составляющих:
3. Pyhon-фреймворк Django aka бэкенд
В разработке фреймворк — это набор готовых библиотек и инструментов, которые помогают создавать веб-приложения. Для примера опишу принцип работы фреймворка Django, написанного на языке программирования Python.
Первым этапом запрос от пользователя попадает в роутер (URL dispatcher), который решает какую функцию для обработки запроса надо вызвать. Решение принимается на основе списка правил, состоящих из регулярного выражения и названия функции: если такой-то урл, то вот такая функция.
Функция, которая вызывается роутером, называется вью (view). Внутри может содержаться любая бизнес-логика, но чаще всего это одно из двух: либо из базы берутся данные, подготавливаются и возвращаются на фронт; либо пришел запрос с данными из какой-то формы, эти данные проверяются и сохраняются в базу.
Данные приложения хранятся в базе данных (БД). Чаще всего используются реляционные БД. Это когда есть таблицы с заранее заданными колонками и эти таблицы связаны между собой через одну из колонок.
Данные в БД можно создавать, читать, изменять и удалять. Иногда для обозначения этих действий можно встретить аббревиатуру CRUD (Create Read Update Delete). Для запроса к данным в БД используется специальный язык SQL (structured query language).
В Джанго для работы с БД используются модели (model). Они позволяют описывать таблицы и делать запросы на привычном разработчику питоне, что гораздо удобнее. За это удобство приходится платить: такие запросы медленнее и ограничены в возможностях по сравнению с использованием чистого SQL.
Полученные из БД данные подготавливаются во вью к отправке на фронт. Они могут быть подставлены в шаблон (template) и отправлены в виде HTML-файла. Но в случае одностраничного приложения это происходит всего один раз, когда генерируется HTML-страница, на который подключаются все JS-скрипты. В остальных случаях данные сериализуются и отправляются в JSON-формате.
4. Javascript-фреймворки aka фронтенд
Клиентская часть приложения — это скрипты, написанные на языке программирования Javascript (JS) и исполняемые в браузере пользователя. Раньше вся клиентская логика основывалась на использовании библиотеки JQuery, которая позволяет работать с DOM, анимацией на странице и делать AJAX запросы.
DOM (document object model) — это структура HTML-страницы. Работа с DOM — это поиск, добавление, изменение, перемещеие и удаление HTML-тегов.
AJAX (asynchronous javascript and XML) — это общее название для технологий, которые позволяют делать асинхронные (без перезагрузки страницы) запросы к серверу и обмениваться данными. Так как клиентская и серверная части веб-приложения написаны на разных языках программирования, то для обмена информацией необходимо преобразовывать структуры данных (например, списки и словари), в которых она хранится, в JSON-формат.
JSON (JavaScript Object Notation) — это универсальный формат для обмена данными между клиентом и сервером. Он представляет собой простую строку, которая может быть использована в любом языке программирования.
Сериализация — это преобразование списка или словаря в JSON-строку. Для примера:
Десериализация — это обратное преобразование строки в список или словарь.
С помощью манипуляций с DOM можно полностью управлять содержимым страниц. С помощью AJAX можно обмениваться данными между клиентом и сервером. С этими технологиями уже можно создать SPA. Но при создании сложного приложения код фронтенда, основанного на JQuery, быстро становится запутанным и трудно поддерживаемым.
К счастью, на смену JQuery пришли Javascript-фреймворки: Backbone Marionette, Angular, React, Vue и другие. У них разная философия и синтаксис, но все они позволяют с гораздо большим удобством управлять данными на фронтенде, имеют шаблонизаторы и инструменты для создания навигации между страницами.
HTML-шаблон — это «умная» HTML-страница, в которой вместо конкретных значений используются переменные и доступны различные операторы: if, цикл for и другие. Процесс получения HTML-страницы из шаблона, когда подставляются переменные и применяются операторы, называется рендерингом шаблона.
Полученная в результате рендеринга страница показывается пользователю. Переход в другой раздел в SPA это применение другого шаблона. Если необходимо использовать в шаблоне другие данные, то они запрашиваются у сервера. Все отправки форм с данными это AJAX запросы на сервер.
5. Как клиент и сервер общаются между собой
Общение клиента с сервером происходит по протоколу HTTP. Основа этого протокола — это запрос от клиента к серверу и ответ сервера клиенту.
Для запросов обычно используют методы GET, если мы хотим получить данные, и POST, если мы хотим изменить данные. Еще в запросе указывается Host (домен сайта), тело запроса (если это POST-запрос) и много дополнительной технической информации.
Современные веб-приложения используют протокол HTTPS, расширенную версию HTTP с поддержкой шифрования SSL/TLS. Использование шифрованного канала передачи данных, независимо от важности этих данных, стало хорошим тоном в интернете.
Есть еще один запрос, который делается перед HTTP. Это DNS (domain name system) запроc. Он нужен для получения ip-адреса, к которому привязан запрашиваемый домен. Эта информация сохраняется в браузере и мы больше не тратим на это время.
Когда запрос от браузера доходит до сервера, он не сразу попадает в Джанго. Сначала его обрабатывает веб-сервер Nginx. Если запрашивается статический файл (например, картинка), то сам Nginx его отправляет в ответ клиенту. Если запрос не к статике, то Nginx должен проксировать (передать) его в Джанго.
К сожалению, он этого не умеет. Поэтому используется еще одна программа-прослойка — сервер приложений. Например для приложений на питоне, это могут быть uWSGI или Gunicorn. И вот уже они передают запрос в Джанго.
После того как Джанго обработал запрос, он возвращает ответ c HTML-страницей или данными, и код ответа. Если все хорошо, то код ответа — 200; если страница не найдена, то — 404; если произошла ошибка и сервер не смог обработать запрос, то — 500. Это самые часто встречающиеся коды.
6. Кэширование в веб-приложениях
Еще одна технология, с которой мы постоянно сталкиваемся, которая присутствует как веб-приложениях и программном обеспечении, так и на уровне процессора в наших компьютерах и смартфонах.
Cache — это концепция в разработке, когда часто используемые данные, вместо того чтобы их каждый раз доставать из БД, вычислять или подготавливать иным способом, сохраняются в быстро доступном месте. Несколько примеров использования кэша:
Делаем современное веб-приложение с нуля
Итак, вы решили сделать новый проект. И проект этот — веб-приложение. Сколько времени уйдёт на создание базового прототипа? Насколько это сложно? Что должен уже со старта уметь современный веб-сайт?
В этой статье мы попробуем набросать boilerplate простейшего веб-приложения со следующей архитектурой:
Введение
Перед разработкой, конечно, сперва нужно определиться, что мы разрабатываем! В качестве модельного приложения для этой статьи я решил сделать примитивный wiki-движок. У нас будут карточки, оформленные в Markdown; их можно будет смотреть и (когда-нибудь в будущем) предлагать правки. Всё это мы оформим в виде одностраничного приложения с server-side rendering (что совершенно необходимо для индексации наших будущих терабайт контента).
Давайте чуть подробнее пройдёмся по компонентам, которые нам для этого понадобятся:
Инфраструктура: git
Наверное, про это можно было и не говорить, но, конечно, мы будем вести разработку в git-репозитории.
Итоговый проект можно посмотреть на Github. Каждой секции статьи соответствует один коммит (я немало ребейзил, чтобы добиться этого!).
Инфраструктура: docker-compose
Начнём с настройки окружения. При том изобилии компонент, которое у нас имеется, весьма логичным решением для разработки будет использование docker-compose.
Добавим в репозиторий файл docker-compose.yml следующего содержания:
Давайте разберём вкратце, что тут происходит.
Не менее важный docker/backend/.dockerignore :
Воркер в целом аналогичен бэкенду, только вместо gunicorn у нас обычный запуск питонячьего модуля:
Наконец, фронтенд. Про него на Хабре есть целая отдельная статья, но, судя по развернутой дискуссии на StackOverflow и комментариям в духе «Ребят, уже 2018, нормального решения всё ещё нет?» там всё не так просто. Я остановился на таком варианте докерфайла.
Итак, наш каркас из контейнеров готов и можно наполнять его содержимым!
Бэкенд: каркас на Flask
Теперь наш бэкенд мы можем официально ПОДНЯТЬ!
Фронтенд: каркас на Express
В дальнейшем нам вообще не потребуется Node.js на машине разработчика (хотя мы могли и сейчас извернуться и запустить npm init через Docker, ну да ладно).
В Dockerfile мы упомянули npm run build и npm run start — нужно добавить в package.json соответствующие команды:
Команда build пока ничего не делает, но она нам ещё пригодится.
Добавим в зависимости Express и создадим в index.js простое приложение:
Теперь docker-compose up frontend поднимает наш фронтенд! Более того, на http://localhost:40002 уже должно красоваться классическое “Hello, world”.
Фронтенд: сборка с webpack и React-приложение
Пришло время изобразить в нашем приложении нечто больше, чем plain text. В этой секции мы добавим простейший React-компонент App и настроим сборку.
При программировании на React очень удобно использовать JSX — диалект JavaScript, расширенный синтаксическими конструкциями вида
Однако, JavaScript-движки не понимают его, поэтому обычно во фронтенд добавляется этап сборки. Специальные компиляторы JavaScript (ага-ага) превращают синтаксический сахар в уродливый классический JavaScript, обрабатывают импорты, минифицируют и так далее.
2014 год. apt-cache search java
Итак, простейший React-компонент выглядит очень просто.
Он просто выведет на экран наше приветствие более убедительным кеглем.
Добавим и клиентскую точку входа:
Для сборки всей этой красоты нам потребуются:
webpack — модный молодёжный сборщик для JS (хотя я уже три часа не читал статей по фронтенду, так что насчёт моды не уверен);
babel — компилятор для всевозможных примочек вроде JSX, а заодно поставщик полифиллов на все случаи IE.
Если предыдущая итерация фронтенда у вас всё ещё запущена, вам достаточно сделать
для установки новых зависимостей. Теперь настроим webpack:
Чтобы заработал babel, нужно сконфигурировать frontend/.babelrc :
Наконец, сделаем осмысленной нашу команду npm run build :
Бэкенд: данные в MongoDB
Прежде, чем двигаться дальше и вдыхать в наше приложение жизнь, надо сперва её вдохнуть в бэкенд. Кажется, мы собирались хранить размеченные в Markdown карточки — пора это сделать.
В то время, как существуют ORM для MongoDB на питоне, я считаю использование ORM практикой порочной и оставляю изучение соответствующих решений на ваше усмотрение. Вместо этого сделаем простенький класс для карточки и сопутствующий DAO:
(Если вы до сих пор не используете аннотации типов в Python, обязательно гляньте эти статьи!)
Теперь надо создать MongoCardDAO и дать Flask-приложению к нему доступ. Хотя сейчас у нас очень простая иерархия объектов (настройки → клиент pymongo → база данных pymongo → MongoCardDAO ), давайте сразу создадим централизованный царь-компонент, делающий dependency injection (он пригодится нам снова, когда мы будем делать воркер и tools).
Время добавить новый роут в Flask-приложение и наслаждаться видом!
Упс… ох, точно. Нам же нужно добавить контент! Заведём папку tools и сложим в неё скриптик, добавляющий одну тестовую карточку:
Успех! Теперь время поддержать это на фронтенде.
Фронтенд: Redux
Начнём с добавления Redux. Redux — JavaScript-библиотека для хранения состояния. Идея в том, чтобы вместо тысячи неявных состояний, изменяемых вашими компонентами при пользовательских действиях и других интересных событиях, иметь одно централизованное состояние, а любое изменение его производить через централизованный механизм действий. Так, если раньше для навигации мы сперва включали гифку загрузки, потом делали запрос через AJAX и, наконец, в success-коллбеке прописывали обновление нужных частей страницы, то в Redux-парадигме нам предлагается отправить действие “изменить контент на гифку с анимацией”, которое изменит глобальное состояние так, что одна из ваших компонент выкинет прежний контент и поставит анимацию, потом сделать запрос, а в его success-коллбеке отправить ещё одно действие, “изменить контент на подгруженный”. В общем, сейчас мы это сами увидим.
Начнём с установки новых зависимостей в наш контейнер.
Первое — собственно, Redux, второе — специальная библиотека для скрещивания React и Redux (written by mating experts), третье — очень нужная штука, необходимость который неплохо обоснована в её же README, и, наконец, четвёртое — библиотечка, необходимая для работы Redux DevTools Extension.
Начнём с бойлерплейтного Redux-кода: создания редьюсера, который ничего не делает, и инициализации состояния.
Наш клиент немного видоизменяется, морально готовясь к работе с Redux:
Фронтенд: страница карточки
Прежде, чем сделать страницы с SSR, надо сделать страницы без SSR! Давайте наконец воспользуемся нашим гениальным API для доступа к карточкам и сверстаем страницу карточки на фронтенде.
Время воспользоваться интеллектом и задизайнить структуру нашего состояния. Материалов на эту тему довольно много, так что предлагаю интеллектом не злоупотреблять и остановится на простом. Например, таком:
Заведём компонент «карточка», принимающий в качестве props содержимое cardData (оно же — фактически содержимое нашей карточки в mongo):
Теперь заведём компонент для всей страницы с карточкой. Он будет ответственен за то, чтобы достать нужные данные из API и передать их в Card. А фетчинг данных мы сделаем React-Redux way.
Для начала создадим файлик frontend/src/redux/actions.js и создадим действие, которые достаёт из API содержимое карточки, если ещё не:
Ох, у нас появилось действие, которое ЧТО-ТО ДЕЛАЕТ! Это надо поддержать в редьюсере:
(Обратите внимание на сверхмодный синтаксис для клонирования объекта с изменением отдельных полей.)
Теперь, когда вся логика унесена в Redux actions, сама компонента CardPage будет выглядеть сравнительно просто:
Добавим простенькую обработку page.type в наш корневой компонент App:
И теперь остался последний момент — надо как-то инициализировать page.type и page.cardSlug в зависимости от URL страницы.
Но в этой статье ещё много разделов, мы же не можем сделать качественное решение прямо сейчас. Давайте пока что сделаем это как-нибудь глупо. Вот прям совсем глупо. Например, регуляркой при инициализации приложения!
Так, секундочку… а где же наш контент? Ох, да мы ведь забыли распарсить Markdown!
Воркер: RQ
Парсинг Markdown и генерация HTML для карточки потенциально неограниченного размера — типичная «тяжёлая» задача, которую вместо того, чтобы решать прямо на бэкенде при сохранении изменений, обычно ставят в очередь и исполняют на отдельных машинах — воркерах.
Есть много опенсорсных реализаций очередей задач; мы возьмём Redis и простенькую библиотечку RQ (Redis Queue), которая передаёт параметры задач в формате pickle и сама организует нам спаунинг процессов для их обработки.
Время добавить редис в зависимости, настройки и вайринг!
Немного бойлерплейтного кода для воркера.
Для самого парсинга подключим библиотечку mistune и напишем простенькую функцию:
Мы объявили свой класс джобы, прокидывающий вайринг в качестве дополнительного kwargs-аргумента во все таски. (Обратите внимание, что он создаёт каждый раз НОВЫЙ вайринг, потому что некоторые клиенты нельзя создавать перед форком, который происходит внутри RQ перед началом обработки задачи.) Чтобы все наши таски не стали зависеть от вайринга — то есть от ВСЕХ наших объектов, — давайте сделаем декоратор, который будет доставать из вайринга только нужное:
Добавляем декоратор к нашей таске и радуемся жизни:
Радуемся жизни? Тьфу, я хотел сказать, запускаем воркер:
Ииии… он ничего не делает! Конечно, ведь мы не ставили ни одной таски!
Давайте перепишем нашу тулзу, которая создаёт тестовую карточку, чтобы она: а) не падала, если карточка уже создана (как в нашем случае); б) ставила таску на парсинг маркдауна.
Пересобрав контейнер с бэкендом, мы наконец можем увидеть контент нашей карточки в браузере:
Фронтенд: навигация
Прежде, чем мы перейдём к SSR, нам нужно сделать всю нашу возню с React хоть сколько-то осмысленной и сделать наше single page application действительно single page. Давайте обновим нашу тулзу, чтобы создавалось две (НЕ ОДНА, А ДВЕ! МАМА, Я ТЕПЕРЬ БИГ ДАТА ДЕВЕЛОПЕР!) карточки, ссылающиеся друг на друга, и потом займёмся навигацией между ними.
Теперь мы можем ходить по ссылкам и созерцать, как каждый раз наше чудесное приложение перезагружается. Хватит это терпеть!
Сперва навесим свой обработчик на клики по ссылкам. Поскольку HTML со ссылками у нас приходит с бэкенда, а приложение у нас на React, потребуется небольшой React-специфический фокус.
Добавляем глупенький редьюсер под это дело:
Внимательный читатель обратит внимание, что URL страницы не будет изменяться при навигации между карточками — даже на скриншоте мы видим Hello, world-карточку по адресу demo-карточки. Соответственно, навигация вперёд-назад тоже отвалилась. Давайте сразу добавим немного чёрной магии с history, чтобы починить это!
Теперь при переходах по ссылкам URL в адресной строке браузера будет реально меняться. Однако, кнопка «Назад» сломается!
А вот как — действие navigate:
Вот теперь история заработает.
Фронтенд: server-side rendering
Пришло время для нашей главной (на мой взгляд) фишечки — SEO-дружелюбия. Чтобы поисковики могли индексировать наш контент, полностью создаваемый динамически в React-компонентах, нам нужно уметь выдавать им результат рендеринга React, и ещё и научиться потом делать этот результат снова интерактивным.