Это видео недоступно.
Сожалеем об этом.
Laravel-data от Spatie: просто и со вкусом! Описание библиотеки.
HTML-код
- Опубликовано: 14 авг 2024
- Фреймворк Laravel, конечно же, давно предоставляет довольно удобные инструменты для валидации и модификации входящих и исходящих (request и response) данных.
Всем нам известны FormRequest, Eloquent API Resource, пакет DataTransferObject (DTO) от Spatie.
Зачем же та же самая компания Spatie создала новую библиотеку, laravel-data? И почему она показалась мне такой интересной? Да просто потому, что эта библиотека, с одной стороны, не привносит ничего особенно нового, а с другой - делает работу по обмену данными более простой и универсальной. Один хорошо написанный с помощью этой библиотеки класс делает всю необходимую валидацию и трансформацию любых данных на любом участке обмена ими. Да плюс ко всему, один дополнительный пакет позволяет ещё и трансформировать эти data objects, написанные на PHP в... описания типов для TypeScript!
Как хотите, но мне этот подход кажется очень интересным. Вот я и создал маленький тестовый проектик, чтобы показать на примерах, как удобно, просто и гибко можно управлять обменом данных в наших laravel-приложениях.
Надеюсь, ролик заинтересует как начинающих, так и опытных PHP и Laravel-разработчиков.
Содержание видео "Laravel-data от Spatie: просто и со вкусом! Описание библиотеки.":
0:00 О чём пойдёт речь
0:40 Чем отличаются объекты полноценных классов от объектов данных (data object)?
1:55 Когда мы используем data objects? Диаграмма потоков данных между клиентами, нашим API и сторонним API.
4:10 Валидация данных, как реквеста, так и респонза.
7:35 Известные инструменты работы с данными в Laravel: FormRequest, Eloquent API Resource, библиотека spatie/data-transfer-object.
11:20 Переходим к обзору laravel-data от Spatie.
12:35 Практикум. Создаём объект данных (data object) для описания персоны. На его примере валидируем и модифицируем данные реквестов и респонзов.
32:20 Подробнее о работе с датами.
36:05 Обзор возможностей laravel-data по документации библиотеки.
37:05 TypeScript-трансформация с помощью laravel-data.
41:10 Заключительные рассуждения.
Полезные ссылки:
➡ Документация библиотеки spatie/laravel-data: spatie.be/docs...
➡ Репозиторий: github.com/spa...
Получать анонсы новых видео можно на нашем телеграм-канале "Глазами фрилансера": t.me/freelance...
#ГлазамиФрилансера #Laravel #PHP
Отлично!!! Спасибо. возник вопрос если мы можем использовать laravel-data как FormRequest как быть в ситуациях когда при создании одно поле required в при редактировании nullable? например при создании пользователя поле password у нас обычно required а вот если хотим обновит нет, мы даже можем не передать поле password, как в таких случаях использовать один класс UserData для валидаций?
Добрый. Например как было сказано в видео использовать MapInputName. Или валидировать посредством RequiredWithout
@@forestlynx Привет, возможно я пока не совсем понимаю как с помощью RequiredWithout и MapInputName решит проблему но не думаю что они нам поможет. Если есть примеры скинь пжл.
Привет, Ерболат!
Смотри, в самом простом случае чем отличается создание от редактирования? При создании у нас ещё нет ID, а при редактировании - есть. Поэтому рауты обычно так и выглядят:
Route::post('/users', [UserController::class, 'create']);
Route::put('/users/{id}', [UserController::class, 'update']);
Тогда что мы можем сделать?
Мы можем добавить в наш UserData:
#[FromRouteParameter('id')]
public ?int $id;
#[RequiredWithout('id')]
public ?string $password;
Обрати внимание, что оба поля - nullable, то есть, не required вообще-то.
Понимаешь, как это будет работать?
Если вызовется route create, поле id не будет заполнено. А значит сработает правило RequiredWithout('id') для пароля
А если вызовется route update, то id заполнится из раута и поле password станет не-required.
Понимаешь идею?
@@freelancer_eyes Добрый день. да теперь понял я почему-то не подумал об этом. Спасибо
Спасибо за материал! Все доступно и понятно. Приятная подача. Мне как новичку, не хватило информации как делать свои кастомные сообщения на ошибки валидации.
Очень интересно вас слушать! Спасибо за ваше время!
Спасибо вам за интерес и поддержку!
Доброго дня! Большое спасибо за видео, очень доступно и понятно! От меня скромное пожелание для будущего видео. Хотелось бы узнать, как готовить свои касты и трансформы в данном пакете, для меня достаточно загадочно использование параметров DataProperty и $context в
public function cast(DataProperty $property, mixed $value, array $context): mixed
PS сам использую этот пакет для json полей. Пока это одно поле, настройки пользователя, - временная зона, аватар, предпочтительная цветовая схема и т.п. - то, что не требует поиска, а потому нет смысла для каждой настройки создавать отдельное поле и миграцию, тем более они будут модифицироваться в будущем. Прописывать их все в одном месте - Data классе - то, что нужно для меня, ИМХО.
Видео просто бомбяо, всё подробно и понятно. Хорошо, что повстречал этот канал :)
Секта святого шпателя изобрела симфони))) kekw
Большое спасибо!
Добрый день! Начал углубляться в пакет и возникла сложность например во входных данных мы можем иметь число, строку или объект(массив). Вот три варианта входных данных: {"status": {
"name": "ACTIVE",
"value": 1,
"label": "Действующая"
},
"legal_form": "LEGAL",
"branch_type": 1}
В классе DTO унаследованного от класса Data пакета в конструкторе определяю свойства:
public EnumDTO $status,
public EnumDTO $legal_form,
public EnumDTO $branch_type
класс EnumDTO так же унаследован от пакета имеет структуру:
public function __construct(
public string $name,
public int $value,
public string $label,
) {
}
По итогу проходит только свойство $status, т.к. его структура соответствует классу EnumDTO, остальные свойства не проходят валидацию. Пытался через WithCast(EnumCastData::class, type: ...::class):
class EnumCastData implements Cast
{
public function __construct(protected ?string $type)
{
dump($this);
}
public function cast(DataProperty $property, mixed $value, array $context): EnumDTO | CannotEnumCast
{
dd($value);
}
}
До dd() не доходит, как я понимаю при инициализации $value происходит приведение ее к типу EnumDTO и тут соответственно происходит ошибка валидации. При трансформации та же проблема. Подскажите как можно решить такую задачу.
В общем очень странное поведение. Первое что проверил исключил внедрение зависимости DTO класса в контроллере, получаю обычный Request и на его основе, получив все поля, через статический метод from создаем DTO при этом преобразование срабатывает. Второй вариант, в классе DTO свойство, в моем случае c типом EnumDTO, исключить из проверки (#[WithoutValidation] public EnumDTO $status). Третий вариант, создать в DTO магический метод public static function fromRequest(Request $request): static {return new self(request->all());} (этот вариант не проверил но из документации к пакету такая возможность имеется).
Думал что это могло зависеть от заголовков запроса, в частности от параметра Accept но он у меня изначально верно указан имеет значение: application/json.
Так и не понял почему происходит такое поведение при внедрении зависимости DTO, хотя судя по документации при внедрении зависимостей преобразование должно срабатывать.
Так это все есть в Response ! Кроме того, там можно добавлять логику. Обработку. Добавлять связи с подчиненными таблицами. Из одного массива создавать коллекции. Ну и интеграция с тестами!!! Пример из документации это 1% от возможностей.
Почему не делаете выпуски про Symfony?
Я уже года два не использовал Symfony (хотя очень люблю этот фреймворк). Просто не подбрасывал таких задач работодатель. Соответственно, немножко подотстал от поезда, не знаю, что там нового и какие тенденции.
Если придётся опять столкнуться с этим монстром - с удовольствием расскажу о свежих впечатлениях.
На счет того, чтобы класс мог называться каноничным с точки зрения ООП - разве камень не будет объектом в реальной жизни? Он имеет свойства, но не имеет поведения. ООП вроде бы как и было придумано как аналогия реальным объектам! Или я ошибаюсь?
По описанию не очень понимаю потребность в этой библиотеке, вся эта функциональность (кроме генерации тайпскриптовых файлов) уже есть в laravel, и часто, если приложение сложнее чем CRUD моделей, структура данных которые мы принимаем отличается от структуры которую отдаем, разве что единый синтаксис для всего этого. Попробую на практике))
Я начал использовать некоторое время назад. Мне нравится, что всё можно описать в едином синтаксисе. Просто публичные свойства, обвешанные аннотациями.
Да, иногда приходится приплясывать, если инпут/аутпут различаются. И я ещё не разобрался во всех возможных путях разрешения этих вопросов.
Но то, что все структуры данных хранятся в одном месте и единообразны - мне таки очень нравится