setupx,
Есть такое понятие BFF (Backend For Frontend).
Это такой бэкенд, который занимается исключительно постройкой SSR разметки для того, чтобы потом Vue в браузере её подхватил и оживил. Этим и занимается Nuxt.
Т.е. мы эту связку Браузер + BFF (Nuxt) называем Фронтендом.
И есть реальный бэкенд, который общается с базой данных, другими сервисами, шлёт email, работает с Telegram и другими социальными сетями, занимается работой с платежными сервисами и т.д и т.п. У этого бэкенда есть своя апиха, при помощи которой он может общаться с вашим BFF, с мобильным приложением, если вы его напишете и т.д.
Таким образом, как всё работает:
- Вы в браузере заполняете формочку, отправляется запрос из браузера в BFF.
- BFF просто перекидывает JSON на сервис Go (ну, может, слегка обрабатывая).
- Go отвечает, и BFF этот ответ передаёт в браузер в том виде, который подходит браузерной части.
Т.е. Nuxt у вас будет простой прокладкой между браузером и сервисом на Go.
Да, эта схема усложняет инфраструктуру, но она хорошо отделяет мух от котлет. И если вас вдруг не устроит Vue, то вы легко сможете его выбросить и перейти на React с Next.js, при этом не изменив ни единой строчки кода на Go. Заказчику будет проще найти специалиста в будущем. Потому что найти спеца Vue + Go неимоверно сложно. А найти спеца по Vue или спеца по Go в десятки раз проще
Я считаю, что наилучшим способом в данном конкретном случае будет банальный эксперимент. Он даст вам больше информации, чем любое жонглирование формулами.
Shurik,
Тут это долго объяснять. Я очень рекомендую вам почитать про DDD (Domain Driven Design), но не копировать бездумно все его подходы, а забрать оттуда то, что вам покажется интересным. Разделение кода на различные use case - это очень толковая идея.
Упрощённо: это когда весь код, касающийся определенного сценария использования, например, создания нового пользователя, хранится в одной директории. Там и сервисы, и тесты, и интерфейсы и т.д.. И тогда при дебаге вы видите всё прямо перед собой, а не скачете по папкам туда-сюда
tukreb, Внимательно прочитайте его проблему. У него есть сущность Town, которая связана с сущностью User. И при запросе POST на создание User надо в поле town подставлять ID сущности Town.
Но что же делать, когда надо будет сделать GET User? Тоже выводить просто ID в поле town, и нагружать фронтенд ещё одним запросом на бэкенд, чтобы вытащить полную сущность Town?
А ведь можно при запросе GET в поле town в JSON подставлять не просто ID, а полностью JSON объект Town, с ID, названием, координатами и т.д.
И в этом случае голый Serializer не поможет, и можно написать для сериалайзера свой нормалайзер, который будет подставлять в поле town нужные данные в зависимости от контекста
tukreb, Маппер для того, чтобы из DTO преобразовывать в сущность и обратно. Писать это всё прямо в контроллере плохо, потому что в один прекрасный день вам понадобится получить данные не через http, а из очереди, из консоли и т.д. Такое очень часто происходит, поэтому тут от принципа KISS можно на один шажок отступить.
Сериалайзер - компонент мощный, но не всегда он может всё сделать. Поэтому иногда в пограничных случаях для него можно написать свой нормалайзер(денормалайзер), который более тонко будет готовить ассоциативный массив перед тем, как сериалайзер его в JSON перекодирует.
Shurik,
Я считаю, что при создании POST вполне можно использовать в DTO поле с id вложенной сущности, и в сервисе маппере уже подставлять в сущность полную вложенную сущность с таким же id.
А при запросе GET можно либо вообще использовать новый DTO, где в этом поле уже будет развернутый объект, либо вы можете в одном DTO использовать все поля, разделяя их при помощи атрибутов сериалайзера Groups и SerializedName, а чтобы одно и то же поле в JSON было в зависимости от POST и GET либо айдишником, либо развернутым объектом, можно написать собственный нормалайзер для сериалайзера. Это очень просто делается. https://symfony.com/doc/current/serializer/custom_...
Кафка - неплохое решение.
Для повышения надёжности можно правильно репликацию настроить.
А на случаи тех редчайших моментов, когда она вдруг будет недоступна, как раз и сделать сбор логов с помощью эластика, либо вообще писать их в файловую систему. А потом либо вручную, либо автоматически как-то обрабатывать эти дропнутые сообщения.
НЕЛЬЗЯ работать с деньгами при помощи float.
Бухгалтера убивают за такое. Погуглите, в чём проблема.
Если вам нужны две цифры после запятой, то используйте копейки вместо рублей. Т.е. умножайте на 100. Таким образом все операции будут проходить над целыми числами, а отображать разряды будете уже исключительно на выходе (на экране, на бумаге).
Rerurk,
"Чем больше интерфейс, тем слабее абстракция." - Роб Пайк.
Использование подхода SMI (Single Method Interfaces) - это один из идиоматических подходов в Go.
Самое первое что приходит в голову для демонстрации, почему это хорошо, - это юнит-тесты. Представьте, что вам нужно протестировать функцию, которая принимает репозиторий в виде параметра, но сама функция использует только лишь один метод Create из этого репозитория. Если вы притащите в качестве аргумента интерфейс с полным набором всех CRUD методов, то вам придётся писать моку, в которой придётся добавить все заглушки в эти методы.
Используя такие интерфейсы, мы можем сделать нашу программу невероятно гибкой. А эти же самые интрерфейсы переиспользовать для совершенно других целей.
Например, у нас может появиться дополнительно к основной какая-то база данных, в которой можно только добавлять записи, но нельзя изменять и удалять. Если мы будем использовать одно-методные интерфейсы во всей нашей программе, то мы сможем переиспользовать почти весь наш код для работы с данными и для этой новой базы данных
Конечно, тяжело без работающего примера, но можно попробовать перед переходом по роутеру остановить анимацию, добавив к элементу с анимацией, например такой класс:
alexalexes, Именно так, в каждом проекте. Потому что бардак в коде гораздо хуже 15 минут, "потерянных" на рефакторинг.
В PHP уже давно есть RFC по запрету укороченных тэгов. И однажды они их таки отменят
Sanes, Лечь рядом с ним и начать плакать.
А если серьёзно, то шансов положить тот же самый nginx, работающий в качестве балансера, крайне мало. У него простая работа - перебросить трафик. Он в базу не лезет, памяти не кушает. А если использовать не свой сервер, а тот же Cloudflare, то там ещё и дополнительные меры принимаются даже против ddos
Есть такое понятие BFF (Backend For Frontend).
Это такой бэкенд, который занимается исключительно постройкой SSR разметки для того, чтобы потом Vue в браузере её подхватил и оживил. Этим и занимается Nuxt.
Т.е. мы эту связку Браузер + BFF (Nuxt) называем Фронтендом.
И есть реальный бэкенд, который общается с базой данных, другими сервисами, шлёт email, работает с Telegram и другими социальными сетями, занимается работой с платежными сервисами и т.д и т.п. У этого бэкенда есть своя апиха, при помощи которой он может общаться с вашим BFF, с мобильным приложением, если вы его напишете и т.д.
Таким образом, как всё работает:
- Вы в браузере заполняете формочку, отправляется запрос из браузера в BFF.
- BFF просто перекидывает JSON на сервис Go (ну, может, слегка обрабатывая).
- Go отвечает, и BFF этот ответ передаёт в браузер в том виде, который подходит браузерной части.
Т.е. Nuxt у вас будет простой прокладкой между браузером и сервисом на Go.
Да, эта схема усложняет инфраструктуру, но она хорошо отделяет мух от котлет. И если вас вдруг не устроит Vue, то вы легко сможете его выбросить и перейти на React с Next.js, при этом не изменив ни единой строчки кода на Go. Заказчику будет проще найти специалиста в будущем. Потому что найти спеца Vue + Go неимоверно сложно. А найти спеца по Vue или спеца по Go в десятки раз проще