Имеется ввиду, что все входные данные читаются не напрямую, а через модель. Это отсекает все лишние проверки, вся бизнес логика построена уже на основе «чистых» данных из модели.
На самом деле фильтрация происходит на разных уровнях:
1) JSON, который приходит в body конвертируется в привычный для Symfony вид, например вот так https://github.com/FriendsOfSymfony/FOSRestBundle/blob/2.0/EventListener/BodyListener.php
Грубо говоря на выходе мы получаем ассоциативный массив
2) В дело вступает первая прослойка data mapper`а: каждое значение этого массива приводится к ожидаемому виду, будь то строка, число, массив или что-то более сложное.
3) Модель получает ВСЕГДА ожидаемое значение, если ожидается строка, а прислали массив – до модели оно не дойдет, отскочит с эксепшеном уровнем выше. Можно сказать, что данные, которые приходят в модель – уже относительно чистые. По-сути data mapper это замена формам.
А дальше модель валидируется на основе Constraint`ов записаных в ней, в случае ошибки – так же улетает эксепшен
После всех этих шагов – мы спокойно работаем с моделью, которая внутри себя содержит все необходимые данные и они нам точно подходят
Отличное выступление, спасибо большое за ссылку на видео.
Я решал немного иную задачу, но многие моменты пересекаются с теми вопросами, что рассматривал Марко, поэтому теперь надо хорошо подумать )
Много чего перепробовал (формы, сериализацию, чистые данные)
Везде есть минусы. Если API нагружено хоть немного то формы и сериализаторы сильно негативно влияют на производительность.
Я остановился на DTO который создается из request с помощью OptionsResolver
В DTO описывают параметры и валидация.
1. Реквест преобразуется в DTO
2. В сервис бизнес логики передается DTO (Тайп хинтинг появляется :) )
3. Сервис возвращает данные которые передаются в Formatter
4. Форматированные данные уходят на респонс
ну чтож, осталось переименовать DTO запросов в команды, сделать для каждой команды отдельные сервисы-хэндлеры, которые не возвращают ничего, и отдельные сервисы которые получают нужное состояние. И получится почти CQRS.
p.s. сам так же делал еще относительно недавно, сейчас все больше и больше нравится подход полного разделения ответственности на чтение и запись. Такой код выходит проще всего поддерживать.
Я же в последнее время вообще не парюсь и юзаю массивчики между контроллерами и приложением. В проектах побольше уже можно загоняться, тогда с валидацией будет проще.
Symfony: обработка запросов в API