Kirill
ты же типы определяешь
Павел
ДТО - это класс для передачи данных, 0 логики. Инвариант - логика
Kirill
а инвариант и есть расширенное определение типа
Павел
инвариант - это описание типа
Ну чет и да и нет, ох уж эта терминология
Kirill
Ну чет и да и нет, ох уж эта терминология
ну инварианты же стираемые, ты можешь удалить их и код должен продолжить работать
Kirill
поэтому я и сказал, что они там где домен обитают
Павел
ну инварианты же стираемые, ты можешь удалить их и код должен продолжить работать
Да не у меня просто немного дисонанс, но это чисто мое. Инвараинт - это правило, которое не может нарушаться. Отчасти логика. Дто - это штука без логики. Но тип (int,string) ты тоже не можешь нарушить))) типизация = инвариант ?))
Павел
Павел
Ой ладно, зря полез в это словоблудие)))
Kirill
Ну вот, а запрос - это не домен
ага, поэтому я и говорю, что там через валидацию проверка типов такая же вполне норм
Kirill
хотя спорно, конечно
Kirill
можно (нужно) и в домене её оставить
Павел
можно (нужно) и в домене её оставить
Двойная валидация, в целом тоже норм
Павел
Конечно нарушает DRY но не всегда
Kirill
так это разные слои
Kirill
одно обеспечивает корректное создание, другое проверку пользовательских данных
Павел
одно обеспечивает корректное создание, другое проверку пользовательских данных
От этого не становится легче когда у тебя одна проверка в 2 местах.
Павел
Когда на реквесте пишешь что емейл - это емейл, и когда в VO еще через какой нить filter var проверяешь, но бросаешь 500
Павел
Или что нейм не должен быть более 100 символов
Kirill
проверка в VO - это вообще впомогательное
Павел
Пишешь констрейнт через ассерт валидатора, а потом еще ручками в сущности
Kirill
основная - в сервисе
Kirill
final readonly class Email implements \Stringable { public function __construct( /** * @var non-empty-string */ private string $email, ) { assert($email !== '', 'Email cannot be empty'); assert(\str_contains($email, '@'), 'Email must contain @'); assert(!\str_starts_with($email, '@'), 'Email cannot starts at @'); assert(!\str_ends_with($email, '@'), 'Email cannot ends with at @'); } // ... }
Kirill
довольно избыточно, конечно
Kirill
final readonly class EmailCreator { // ... public function create(string $email): Email { $violations = $this->validator->validate(...); foreach ($violations as $violation) { throw new InvalidEmailDomainException($violation->getMessage()); } return new Email($email); } }
Kirill
final readonly class CreateUserController { public function __invoke( #[MapRequestPayload] UserCreateRequestDTO $dto, ) { try { $user = $this->users->create($dto->name, $dto->email); } catch (DomainException $e) { throw new UnprocessableEntityHttpException(...); } return $this->transformer->toResponse($user); } } final readonly class UserCreateRequestDTO { public function __construct( /** @var non-empty-string */ #[Assert\NotBlank] public string $name, /** @var non-empty-string */ #[Assert\NotBlank] public string $email, ) {} }
Kirill
Вот и получаем, что валидацией DTO просто проверяется пользовательский ввод, а бизнес логика уже в сервисах
Kirill
блин, я тут подумал, действительно, для простых правил - это очевидное дублирование проверок)
Kirill
ты прав
Dmitry
Привет! Грохнул репозиторий, вернее env файлы, как можно новые сгенерировать, чтоб все переменные окружения восстановились, пусть даже с дефолтными данными
Юра
Скопировать .env.dist
Юра
И назвать его .env
Юра
От версии симфы зависит еще
Юра
Ну и если они были в репозитории то можно же восстановить
Михаил
Не знаю, есть ли что-то типо dump:env команды, но можешь попробовать по ide поискать регуляркой. Сложность в том что переменные пишутся так же как и константы, но думаю ты справишься Можно подцепиться к dotenv и принтить имя переменной каждый раз когда кто-нибудь её запрашивает в коде. Думаю через несколько перезапусков и актуализаций списка ты востановишь.
Михаил
Ну и это, а как же работать под гитом?
Aleksandr Khristenko
Так а .env ведь часто под гитигнором, в гит обычно .env.dist попадает
Михаил
Так а .env ведь часто под гитигнором, в гит обычно .env.dist попадает
Так я про это и говорю. От туда и восстановить
Nikolay
Интегрирую symfony/messenger в проект. Возникли вопросы по поводу запуска/остановки воркеров. В доке говорится, что надо при деплое стопать воркеры через команду messenger:stop-workers. Если через supervisor настроен процессинг, то получается надо еще запускать sudo supervisorctl stop messenger-consume:* до деплоя и старт после деплоя, я правильно понимаю?
SK
во вторых - во время деплоя запускают сервисы а не стопят
Nikolay
начнем с деплоя через sudo - ты что то делаешь не так
Это просто из доки пример, понятно что не через судо
Nikolay
во вторых - во время деплоя запускают сервисы а не стопят
Это если все в контейнерах, а в текущем проекте их пока нет
SK
Это если все в контейнерах, а в текущем проекте их пока нет
ну типо тогда чего не стопнуть апач с нджинксом ?
SK
супервизор не трогай, команду делай
SK
всё
SK
Обязательно быть таким токсичным?
я не стал дожидаться команду телепатов,чтобы они сказали где ты ступил и сам полез читать доку, ты мне обязан должен быть что я сделал то, что ты должен был сделать изначально
Павел
Это если все в контейнерах, а в текущем проекте их пока нет
Если деплоится через какой нить деплоер, и деплой через симлинк, то возможно еще будет прикол в том, что стопнуть в прошлом релизе.
Павел
Как раз так и деплоится через CI deployer-cli <command>
У меня были проблемы, что работало в старом релизе, приходилось именно лезть в прошлый и стопать там, но возможно я у себя что не разобрался, но лучше иметь ввиду, что такое возможно
Павел
Как раз так и деплоится через CI deployer-cli <command>
task( 'queue:restart', function () { run('cd {{previous_release}} && {{bin/php}} bin/console messenger:stop-workers'); } ); task( 'deploy:after', function () { invoke('reload:php-fpm'); invoke('queue:restart'); invoke('env:local-php'); } ); на правильность не претендую, но какие то свои проблемы решил и это вроде работает. супервизорд не трогаю.
Chingis
Это как у Гуфа: сегодня завтра было вчера, а еще вчера сегодня было завтра. after('deploy', 'deploy:after');
Павел
Я же правильно понимаю, что после окончания деплоя просто стопаются воркеры и все?
Да, получается они дорабатывают в старом коде свой полный цикл, стопаются, а супервизорд поднимает уже в новом
Anton
Всем привет! Накидал статейку на Хабре про написание расширяемых сервисов: https://habr.com/ru/sandbox/231718/
Павел
Всем привет! Накидал статейку на Хабре про написание расширяемых сервисов: https://habr.com/ru/sandbox/231718/
Можно без "компайлер пасса", навесить на ErrorHandlerInterface AutoconfigureTag без tagName чтобы имя тега стало FQN интерфейса , а потом #[AutowireIterator(ErrorHandlerInterface::class)] Будет отсутствие действий в кернеле при каждом таком AutowireIterator
Anton
Можно без "компайлер пасса", навесить на ErrorHandlerInterface AutoconfigureTag без tagName чтобы имя тега стало FQN интерфейса , а потом #[AutowireIterator(ErrorHandlerInterface::class)] Будет отсутствие действий в кернеле при каждом таком AutowireIterator
Да, тоже хороший вариант. Думал изначально так написать, но решил через кернел, т.к. хотелось показать более наглядную реализацию, а не уходить в магию уровня "Вот тут пишем атрибут и все работает" =D
Nikolay
Всем привет! Накидал статейку на Хабре про написание расширяемых сервисов: https://habr.com/ru/sandbox/231718/
Интерфейс вроде один лишний и не используется, или я пропустил что-то
Anton
Интерфейс вроде один лишний и не используется, или я пропустил что-то
У нас там дефолтный хендлер, который обрабатывает оставшиеся исключения. И для него isApply не нужен, т.к. мы принимаем в нем любой Exception
Anton
Да и если для всего использовать 1 интерфейс, то Симфа соберет нам в список хендлеров и дефолтный, а он нам там не нужен. Поэтому и решил разделить интерфейсы)
Anton
В новой версии появилась возможность вроде исключать, но это не точно
Не знал, что как-то можно исключать что-то на уровне контейнера
Павел
На 6.4 точно уже есть
#lest
Когда я меняю пароль к бд в env и поднимаю заново контейнеры у меня все равно стоит пароль от бд, удалял образы бд, не помогает, помогает только полное удаление данных докера через docker system prune -a, как вы решаете такую проблему
#lest
Я думаю должен быть правильный способ они как у меня
#lest
Только заходить, нельзя чтобы просто поменять в енв пересобрать и работать?
#lest
И еще, я внутри докерфайла делаю установку зависимостей, но на самом сервере папку vendor не видно, внутри она есть, volumes прокиданы, это нормально?
Aleksandr Khristenko
И еще, я внутри докерфайла делаю установку зависимостей, но на самом сервере папку vendor не видно, внутри она есть, volumes прокиданы, это нормально?
Так если у тебя установка зависимостей была в момент билда образа, а вольюмы ты подключаешь в момент запуска контейнера то как ты ожидаешь снаружи эту папку получить?
#lest
При загрузке на сервер файла она же снаружи видна
#lest
Я думал volumes работают по типу стрима в обе стороны, почитаю насчет этого