Комментарии 125
Что мы покроем:
настройка dev-окружения в docker-compose.
создание бэкенда на Flask.
создание фронтенда на Express.
сборка JS с помощью Webpack.
React, Redux и server side rendering.
очереди задач с RQ.
Очень интересно, почему выбран именно такой стек.
Вообще оно больше всего мне напомнило вот эту статью про то, как люди пытаются выучить современный JavaScript: habr.com/ru/post/312022
![image](https://habrastorage.org/getpro/habr/comment_images/66c/82f/af1/66c82faf1f8cea4d11059dea3503fa6d.gif)
У меня была цель написать статью именно про подготовку проекта with good design.
Из того, что быстро нашлось на Хабре:
«До микросервисов нужно дорасти, а не начинать с них» habr.com/ru/post/427215
«Преступный переинженеринг» habr.com/ru/post/99889
Как вы смогли применить слова «оптимизация» и «усложнение» как синонимы, я тоже не понимаю, ну да ладно.
(Не помню из чьего доклада и на какой конференции)
Но опять же, это имхо.
Статья интересная, но вот возник вопрос, почему именно синхронный Flask? Есть какие-то еще плюсы кроме того, что уже знаком многим и относительно простой в использовании?
BTW, в статье изменения коммитятся в одно место, не понимаю, о каких двух местах речь.
Слить бэкенд и фронтенд можно было бы, сделав весь бэкенд на Node.js, но как-то не хочется.Возможно бэкенде совсем не нужен с этой штукой www.prisma.io? Особенно если сапописанный бэкенд это мерзкий питон и под реакт (который самый первый потребитель graphql)? Идеальный код это ведь ненаписанный код.
Ненаписанный код — это, конечно, хорошо, но едва ли реализуемо в хоть сколько-то нетривиальном приложении.
Особенно если сапописанный бэкенд это мерзкий питон
При живом Go, Nodejs, и даже, прости господи, PHP делать web на питоне, по крайней мере, странно.
Эти отступы, двойные подчеркивания, явный self и document[«id»] вместо document.id сделаны как-будто специально, чтобы вывести из равновесия даже самого флегматичного кодера.
Сам по себе язык не хуже других, но эстетические чувства раз от разу страдают.
хотя я уже три часа не читал статей по фронтенду, так что насчёт моды не уверен
вот тут вы правы 100%! :)
И залпы тысячи орудий
Слились в протяжный вой…
О том, что здесь использована стрельба из крупнокалиберных орудий по малым целям, уже написано.
Я же со своей стороны хочу отметить, что
- называть любой кусок серверного кода «фронтэндом» — плохая практика, большинство разработчиков резервирует это слово для кода, выполняемого исключительно на клиенте, вместо вашего «frontend» стоит употреблять router, а вместо «backend» — API-server
- при наличии живого роутера, делать прямой доступ с клиента аджаксом на апи-сервер — нарушение инкапсуляции и создание проблем с CORS на ровном месте
В начале у меня было ощущение, что это просто очень хорошая, но очень злая ирония. Но потом зашёл в комментарии, и нет, всё серьёзно и на самом деле достаточно грустно.
А мне статья понравилась и автор большой молодец. С несколькими но:
Решение явно не для продакшена.
Решение показывает как можно делать, если вам нужен реакт, как можно делать если нужно при на флажке и так далее, охватывая все аспекты.
Решение не должно носить характер how-to, так как тут предлагается на завтрак зажарить целого кабана, сделать карпачо и фуагру, после чего приготовить ещё и пиццу.
btw, гугл сейчас отлично и client side rendering понимает.
- Google — не единственный поисковый движок;
- сокращение времени до первого информативного рендера положительно сказывается на user experience.
Доклад по теме с Google I/O 2018
Так же существует такой распространенный кейс, как шаринг контента в приложениях и социальных сетях. SSR в данном случае нужен для рендера разметки Open Graph.
app.get()
? Такое себе. Голая нода тоже это умеет.Замечательная статья, спасибо большое. Не слушайте всех кто говорит про переусложнение, это очень полезный материал для тех кому нужен хороший дизайн.
я считаю использование ORM практикой порочной и оставляю изучение соответствующих решений на ваше усмотрение
Почему?
frontend / backend
Может лучше SSR-server / API-server ?
Жду следующую статью с "логирование, мониторинг, нагрузочное тестирование.".
Извините, много сумбурного текста…
Сегодня, практически часа 3 назад, обратился давний знакомый, много проектов разных вместе сделали за овер 10 лет… Попросил внести мелкие изменения для сайта
Два слова о проекте: сайт подобие соц.сети для публикации проблем\вопросов\етс. граждан и специальная команда (юристы, представители депутатов и т.п.) рассматривают вопрос… тоесть там и блог, и админка, и кабинет пользователя и разные сущности записей… крч. куча разных функций с множеством разграничений доступа…
Сайт был сделан лет 5 назад, если не 6ть…
И знаете что? Я был в шоке… в положительном смысле… крутиться это чудо на самом дешевом vps, но сам сайт летает… там нет космических технологий и т.п., делалось тупо в лоб и по простому…
Начинаю вспоминать последние 2-3 года и разные компании в которых доводилось работать.
Любой сайт\ресурс, это как минимум: прожект.менеджер, программисты бекэнд (а может и не один), фронтенд (а может и два), дев.опс, какой нибуть админ, дизайнер (а может и два), и еще разные лица вовлеченные по дороге реализации проекта… И огромный стек технологий… начиная c ангуляроа (к примеру), заканчивая CI/CD, TDD, разными менеджерами очередей, и все это, конечно, в облаке…
И самое страшное: клиенты платят за весь этот шабаш…
Причем вся эта куча и весь кипиш с техно-хайпом неоправданое усложнение относительно простого проэкта.
Смотрю на свой код 5ти летней давности… из технологий php5, mysql5, jquery, html,css… все… просто, тупо, плоско, понятно… очень легко разобраться спустя столько времени… без сервисов, промежуточных окружений и т.п., простые sql-запросы без orm-генераций…
Посмотрел и сравниваю сделанные проекты лет 5 назад, и то что делаю последнее время. И знаете что? Проекты по сути похожи своими функциями, лишь разница в стеке технологий и числе вовлеченного персонала. Но есть существенное отличие в методике реализации «современных» проектов: сложность реализации (из-за тех.стека и лиц которыми нужно управлять), и далее пошло-поехало: слабая оптимизация из-за фреймворков для нетривиальных задач, отсюда трафик, вдс принято считать слабым звеном — значит проект в облаке, может быть в aws, авс для абы-как сделанных проектов (пусть сервисов) не такое дешевое удовольствие… и т.д. и т.п. (грусть печаль)…
Раньше то что делалось 1-3 месяца до полного адекватного безбажного релиза, сейчас в год не укладывается… (пример последних 2х компаний над проектами которых трудился)…
Не знаю точно в чем дело, но я убежден, множество элементов (технологий) необходимых для современного проекта лишь вредит, особенно запуску первого релиза, не говоря о дальнейшем сопровождении, к небесам возвышает стоимость рабработки, усложняет сам процес, и т.д. и т.п., похоже, разучились искать простые решения сложных задач.
И самое страшное, многое из того то что пытаются применять — ни к месту, в предпоследней конторе заявили: нам нужен rabbitQL потому что не хотим казаться лохами в глазах заказчика (а задача, на самом деле, решалась в 3 функции и 1 map)
Потому, меня тошнит от нашей современности… npm, typescript, react, angular, docker, docker-compose, k8s, mongodb, mysql, golang, aws, ci\cd — это не полный список того из последнего проекта… А проект — цмс-каталог для управления разными сущностями, грубо говоря, у тебя 10 таблиц в бд, и каждому из пользователей настраивается право доступа к данным + разрграничения прав в пределах таблицы… абсолютная тривиальщина… но делается больше 1.5 года, только за 1й год разработки страшные счета за авс… сейчас оно запущено, работает, но частенько появляются новые узкие места…
Вот такие дела…
Но тут, наверное, мы попадаем на типовую «боль» современных разработчиков — а именно, что слишком часто идет переусложнение типовых вещей.
Аналогично — занимаюсь веб-разработкой уже 15 лет. Работаю в малых проектах, пишу архитектуру, код (LAMP, на клиенте в очень небольших местах JS/JQuery). Недавно решил прогнать нагрузочное тестирование, просто для оценки, сколько может выдержать небольшой VDS.
Оказалось — 10-20 тысяч клиентов в сутки (которые активно взаимодействуют с сервисом, а не просто посмотрели пару страничек)! Пиковая нагрузка до начала «подтормаживания» — что-то около 300 запросов в секунду. Это без специальных оптимизаций и докупки железа (очевидно, что железа на 1-2 машины всегда легче докупить, чем оплатить работу программиста).
Естественно, этого будет мало для любой бесплатной соцсети/инстаграмма/мессенджера и пр. Но для абсолютного большинства малых и средних платных сервисов (и магазинов) такого хватает с головой.
Как был приведен пример — просто слишком часто бывает ситуация, когда в проекте нужно администрировать 10-20 табличек в БД, и под него начинает наворачиваться докер, SPA, микросервисы… И чем думают техдиректора в таком проекте, мне прям сложно сказать.
похоже ноги растут не от желания решать бизнес задачи клиента, а от желания развивать свой ИТ-бизнес.
как писал в одном из комменте не так давно: я программирую после работы. =)
я знаю о чем они думаю
В действительности, Вы просто экстраполируете свой опыт на всех. Вы говорите, что технологии используются в угоду "техно-хайпу" и в угоду спекулятивного роста компании. Печально, если Вам приходилось сталкиваться с подобной практикой, но это не отменяет того, что технологии могут использоваться по назначению, и что это может происходить осознанно. Поэтому Ваша патетика в начале треда выглядит не очень уместной.
1. — весь этот зоопарк технологий сегодня превратился в мейнстрим, его использует только не ленивый, все проекты за посл.время перегружены всем этим, вот правда, не встретил по настоящему высоконагруженный проект…
2. — перегрузка проекта метриками, фреймворками и т.п. сами по себе неоправданно увеличивают расходы проекта (трафик\запросы), основная моя компания в которой работаю уже более 7ми лет с самого начала ее основания не использует не то что облачные сервисы и чудовищной инфраструктуры, а и в кластере не было и нет необходимости, все по тому, что ядро и код писался нативно, и проблемы с всплесками трафика и дикой нагрузкой решались на уровне оптимизаций кода и алгоритмов, до сих пор все крутиться на 1 железном серваке… за все время озу лишь добавили и 4тб места…
PS: простой пример, паралельно занимались разработкой микросервисов для 2х разных проектов в одной компании, я один над одним, команда разработчиков-подрядчиков над другим… у них сервис авторизации стал узким горлышком (все сервисы валидировали запросы и авторизировались через сервис авторизации), я же сервис авторизацию построил только для изменения пользователей, и каждый из десятка других сервисом содержат в своей БД таблицы сервиса авторизации и на основе репликации изменения в пользователях попадают на слейвы (сервисы отличны от auth)… это не только сократило чудовищный трафик и rps между сервисами, но и положительно повлияло на отклик целевого сервиса…
Я старый программист, 15лет практики в ИТ — целая эпоха, строго не судите.
Вы привели в пример Facebook, но во первых, у Facebook достаточно специфичные задачи, а во вторых я не считаю, что это хороший пример производительности и безпроблемной работы. К тому же, смотреть как сделано у больших дядей и повторять за ними — глупо. У вас нет ни таких ресурсов, ни таких требований. Ваша архитектура избыточно сложна и зависит от стольких технологий, что будет сложно подобрать команду, чтоб человек пришел, сел и начать работать. Для стартапа — это минус. У них нет времени на обучение.
Всё, что вы сделали в половине статьи, можно сделать, подняв Контейнер со Spring Boot на Back'end за 10 минут. И разработчиков проще найти и комплексность в разы меньше.
Вы ведь понимаете, что все технологии, фреймворки — они не для сайта на одной vpsке с одним разработчиком?
Нет.
Все эти технологии, фреймворки и так далее — это инструменты упрощения разработки. Ну, в теории, должны быть.
На практике каша разных технологий дико повышает порог вхождения и дает огромные накладные расходы.
И в этом проблема вашей статьи.
Она не учит писать проекты с нуля и не объясняет как их нужно разрабатывать.
Она приучает к определенному узкому стеку инструментов. Без которых, якобы, ничего сделать нельзя.
Картинку про троллейбус из буханки хлеба знаете?
Да и не только перед новичком.
Сложно — потому что не нужно.
А главное, все эти инструменты не научат его делать сложные проекты. Потому что не учат главному — алгоритмам, причинам и следствиям. Эти инструменты привяжут его к определенному стеку.
Категорически не согласен с этим постом.
Первый раз с веб разработкой имел дело году так в 2010 (html, css, php)
Потом перерыв больше 10 лет - и пришлось заново осваивать как раз после нового года 2023 года.
Так вот, прогресс просто колосальный.
А всё это усложнение нужно - чтобы запускать сайты, которыми пользуются миллионы людей.
Масштабирование - мечта любого стартапа.
И есть ошибка в в основной архитектуре на которой все строится: фронтенд, который берет на себя слишком много функций и реализует все это на ЯП, в котором, из-за отсутсвия полноценного ООП, очень сложно организовать код без доп. фреймворков. И из-за этого и требуется писать столько лишних костылей.
Я с интересом наблюдаю, как фрондендщики изобретают бэкэнд заново: сервер-роутер, рендер сервер. И спрашиваю себя: а у JS-way подхода точно больше плюсов? Или новые фишки придумываются чтоб подпереть старые костыли?
Для сложного — JAVA, C#
3 года назад мне один сказал, что нет ничего лучше NodeJS, только он то боролся с утечками памяти, то переписывал под TypeScript, потому что устал бороться с проверками на тип, то еще что-то…
А приложение на PHP как работало тогда без проблем, так и сейчас работает. Может не так быстро, то полусекундная разница в загрузке страницы — не так уж решает.
И чем же в вашей школе тогда пользуются?
И давно это JS стал нормальным языком?
По-моему, ему однажды повезло быть встроенным в браузеры и теперь от этого legacy-говнища хрен избавишься.
Но конечно каждому своё.
Это всё конечно круто, спасибо за статью.
Но почему бы не отдавать сформированный динамически при каждом запросе готовый html контент прям на Python, а на JS если нужно сделать какой-то интерактив? Для чего нужен React+Redux?
Есть разные штуки вроде гуглокарт и гуглопочт, где нужно делать на стороне браузера именно приложение. Но подавляющее большинство остальных случае, это именно сайт, со страницами и контентом. Нафига делать простой сайт как сложное одностраничное приложение?
Вместо простой и быстрой отдачи html и удобного бекенда на любом языке, выбирать всякие заморочки на фронте. Не слишком ли усложнился фронтенд на пустом месте и без необходимости?
жду продолжения с юнит тестами, selenium и регрессивными тыстами =)
Вот вы говорите, что этот подход — из пушки по воробьям. Ну ок, но ведь не все ограничивается блогами и досками объявлений. Вам не кажется, что автор в статье просто хотел показать разработку сайта «от и до»? Или он должен был все это показать на примере разработки аналога фейсбук? Это ж просто пример, вовсе не означающий, что блогоподобные сайты надо делать именно так.
По поводу того, что ssr не нужен, и это лишнее звено. Это достаточно спорное утверждение. Я считаю, что SSR в 2019 до сих пор нужен, даже несмотря на то, что гугл умеет сайты на js индексировать. Во-первых, кроме гугла есть еще и другие поисковые системы, а, во-вторых, насколько я знаю, он до сих пор такие сайты индексирует хуже обычных.
А показать зачем надо было их потерпеть и какой пряник мы получаем из-за этого — нет, без этого смысл расчехлять BFG?
О Docker-контейнеризации. Можно все разворачивать и без контейнеров, но так ли уж проще без докера будет следить за тем, чтобы тестовое окружение не отличалось от локального разработчиков и продового? На такие вещи закрывать глаза нельзя, а ставить все везде в нужных версиях на голое железо вряд ли будет проще.
Рендеринг на сервере. Да, можно было не заморачиваться, отказавшись от него и оставив фронт на реакте, который дергает апи (бэкенд). Это было бы проще, но статьи с такого блога видел бы только гугл (и то плохо), а для остальных поисковиков ваш сайт бы состоял из пустых страниц.
Если делать сайт, рендеря по-старинке html на сервере средствами пхп/питона, то сделать нормально сложный качественный поддерживаемый фронтенд для этого всего достаточно сложно. А уж про отзывчивость такого интерфейса говорить, думаю, не надо, потому что сайты в виде SPA работают при переходе по страницам плавно и приятно — никакой полной перезагрузки страницы. Тут спорить можно долго: надо просто попробовать и сравнить. Можно то же самое сделать руками на jQuery, загружая аяксом контент статей блога, но тут опять упираемся в сложности с рендерингом на сервере. А, кстати, вручную настраивать системы сборки js и css для задач типа обфускации js-кода, объединения в один файл и т.п. для самописного фронта — так ли уж это проще разве?
Так что в итоге два варианта: либо так, заморочившись с инфраструктурой (хотя лично я тут не вижу сложностей вообще), либо ваять сайты по-старинке с бэком, где рендерятся шаблоны, а на фронте jquery-лапша. Учитывая мой опыт поддержки легаси-проектов, написанных с использованием второго подхода: нахрен оно надо вообще. И не проще это ни разу, особенно когда проект растет, а его фронтенд становится сложнее и сложнее.
Бэкенд-разработчики разрабатывают API, отдают фронтенд-разработчикам файл swagger.yml, по которому фронтенд-разработчики независимо делают фронтенд. Каждый занят своим делом.
На мой взгляд, такая инфраструктура явно выглядит лучше, чем рендеринг шаблонов на сервере с какими-то шаблонными тегами, завязанными на особенности фреймворка, обучение фронтенд-разработчиков конструкциям шаблонизатора и последующие прикручивание, как почему-то до сих пор модно, jQuery, потому что React/Angular/Vue — это сложно, а потому не нужно.
А что касается вероятности переписывания, то сайт, у которого фронт сделан в виде jQuery-лапши, а шаблоны рендерятся на сервере, намертво вколоченные в какой-то фреймворк и его особенности, может быть потому и не переписывают, потому что переписать такое без боли просто невозможно?
Только там на входе была модель в XML, которая рендерилась на сервере с помощью XSLT и отдавалась целиком, а потом отдельные куски приезжали клиенту через AJAX в XML и там уже преобразовывались через XSLT в XHMLT и вставлялось в нужные места.
Но я давно ушёл из веба в профессиональном плане, хотя немного общие тенденции стараюсь отслеживать.
Ну по сути оба подхода одинаковы (в случае простого сайта конечно, а не чего-то вроде клиента телеги).
- Либо на сервере вся логика и генерация_html, а на фронте чуток JS/jQuery.
- Либо наоборот на сервере только API, а уже на фронте вся логика/ маршрутизация/генерация_html.
Одинокие
Во втором случае существует профессия фронтендер :). Конечно этот вариант может быть более оправдан в ряде случаев, особенно при постоянных сменах дизайна и когда бекендеры испытывают отвращение к JS и всему моднобраузерохипстерскому.
А достаточно же просто файла.html,
<h1>Hello, word!</h1>
и браузера для того, чтобы им открыть и увидеть результат.Хотя и интересно.
Понятно что имелось ввиду «Так делают крутые дяди из гугла/фейсбука/вставь_своё, ибо куча плюшек!», но без показа этих самых плюшек, BFG тут выглядит прям очень лишним.
Довольно печально что в наше время уклон идёт в инструменты, а не решение задач.
Как посмотрю сколько модулей, так вспоминаю KISS и плакать хочется =)
format MZ
heap 0
stack 100h
entry main:start
segment main use16
start: push 0
pop fs ; vector table
mov ax,data_segment
mov ds,ax
mov es,ax
mov ax, 13h ; modeX Graphics 320x200x256, 40x25, 8x8
int 10h
mov eax, dword [fs:43h*4]
mov dword [int43], eax ; Get 8x8 chargen ptr
mov si, hello
next: call gotoxy
lodsb
or al,al
jz exit
cmp al,20h ; ?
jnz @1
add byte [Y], 11
mov byte [X], 0
jmp next
@1: movzx ax,al
shl ax, 3 ; ax*8
push si
push ds
lds si, [int43]
add si, ax
; Вывод на экран
mov cx, 8
loo0: lodsb
mov bl, al
push cx
mov cx, 8
loo1: mov al, 20h
rcl bl, 1
jnc @@1
mov al, 0DBh
@@1: int 29h
loop loo1
pop cx
inc byte [es:Y]
call gotoxy
loop loo0
pop ds
pop si
add byte [X], 8
sub byte [Y], 8
jmp next
; выход
exit: xor ah, ah
int 16h
mov ax, 03h
int 10h
mov ah, 4Ch
int 21h
gotoxy: pusha
mov ah,2
xor bx,bx
mov dx, word [es:XY]
int 10h
popa
ret
segment data_segment use16
int43: dd ?
XY:
X: db 0
Y: db 3
hello: db 'Hello world',0
org 0x100
mov dx, msg
mov ah, 9
int 0x21
iret
msg db 'Hello, World!', 0x0d, 0x0a, '$'
C iret'ом улетите далеко и надолго. Кроме смещения он вытаскивает со стека и восстанавливает сегментный регистр и сохраненные флаги, что, скорее всего, закончится фатально для DOS (или её эмулятора).
Бэкенд. Повелитель бизнес-логики, наш бэкенд будет небольшим Flask-приложением. Данные (наши карточки) будем хранить в популярном key-value хранилище MongoDB
А с каких пор mongoDB стала key-value хранилищем?
Есть aiomongo и aiohttp. Вот пример api на нем dev.to/apcelent/how-to-create-rest-api-using-aiohttp-54p1
Делаем современное веб-приложение с нуля