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
MishaXXL,
Не нужно стремиться делать код "красивым". Нужно стремиться делать код читаемым, чтобы он был понятен сразу, с первого взгляда. А вот побочным эффектом читаемости как раз может стать та самая "красота".
Кстати, ещё совет: чтобы избегать непоняток с тем, когда срабатывает тот самый ++, старайтесь его не использовать там, где это возможно.
// Вместо этого
i++;
// Лучше вот так.
i = i + 1;
// или
i += 1;
Да, код может стать чуть длиннее. Да, вместо одной хитрой строчки может появиться две простые строчки. Но, читая код, вы не будете задумываться над тем, а когда же произойдет этот самый ++, когда изменится переменная. Это может избавить вас от многих багов. Простота лучше "красоты"
suspect47, 2 Гб - это очень много. Бубунта столько всякого ненужного мусора устанавливает, что просто страх. Даже у Плазмы будет значительно меньше. А если посмотреть в сторону минималистичных окружений, то вот тут вы увидите, что такое "летает" на самом деле.