Валідація запитів контролера за допомогою пакету Laravel Data

Перекладено ШІ
Оригінал: Laravel News
Оновлено: 20 травня, 2025
Laravel Data - це потужний інструмент, який відкриває нові можливості для валідації запитів у ваших застосунках. Чи важливо для вас дізнатися, як використання об'єктів даних може спростити цей процес? Читайте далі та розкрийте захопливі можливості валідації з Laravel Data!

Пакет Laravel Data пропонує безліч чудових можливостей для роботи з об’єктами даних у додатках Laravel. Об’єкти даних є багатими, типізованими та налаштовуваними, їх можна використовувати як API-ресурси, форму запитів, визначення TypeScript та інше.

Однією цікавою можливістю, яку я спочатку не помітив, є використання об’єктів Laravel Data для валідації запитів у контролерах. Фактично, об’єкти даних мають потужний механізм валідації, який можна використовувати різними способами. Розгляньмо простий приклад об’єкта ArticleData:

namespace App\Data;
 
use Carbon\CarbonImmutable;
use Spatie\LaravelData\Data;
 
class ArticleData extends Data
{
    public function __construct(
        public string $title,
        public string $content,
        public ?string $description = null,
        public ?CarbonImmutable $published_at = null,
        public ?CarbonImmutable $created_at = null,
        public ?CarbonImmutable $updated_at = null,
    ) {}
}

Неочевидно, але цей об’єкт автоматично визначає правила валідації:

App\Data\ArticleData::validate([])
 
// Illuminate\Validation\ValidationException  Поле заголовка є обов'язковим. (та ще 1 помилка).

Ми не розглядатимемо всі аспекти валідації у Laravel Data, але документація з валідації детально розповість про все. Валідація чудово налаштовується і добре інтегрується з Laravel.

# Використання Laravel Data для валідації запитів

Розгляньмо наш приклад статті і використаємо об’єкт для валідації створення запису в базі даних через наш уявний контролер Article:

namespace App\Http\Controllers;
 
use App\Data\ArticleData;
use App\Models\Article;
 
class CreateArticleController extends Controller
{
    public function __invoke(ArticleData $data)
    {
        $article = Article::create([
            'title' => $data->title,
            'content' => $data->content,
            'description' => $data->description,
            'published_at' => $data->published_at,
        ]);
 
        return response()->json(ArticleData::from($article), 201, [
            'Location' => route('article.show', $article),
        ]);
    }
}

Якщо ми напишемо тест для цього, щоб спровокувати стандартну валідацію, він виглядатиме так:

#[Test]
public function it_validates_article_creation()
{
    $response = $this->postJson('/article', []);
 
    $response->assertStatus(422);
    $response->assertJsonValidationErrors([
        'title' => 'Поле заголовка є обов'язковим.',
        'content' => 'Поле вмісту є обов'язковим.',
    ]);
}

Припустимо, ми хочемо зробити параметр published_at необов’язковим, але при цьому перевірити, щоб формат дати відповідав очікуваному:

// app/Data/ArticleData.php
use Spatie\LaravelData\Attributes\Validation\DateFormat;
 
#[DateFormat(DATE_ATOM)]
public ?CarbonImmutable $published_at = null;

Якщо ми надішлемо поле published_at з неправильним форматом, отримаємо такі помилки валідації у форматі JSON:

{
    "message": "Поле заголовка є обов'язковим. (та 2 інші помилки)",
    "errors": {
        "title": [
            "Поле заголовка є обов'язковим."
        ],
        "content": [
            "Поле вмісту є обов'язковим."
        ],
        "published_at": [
            "Поле дати публікації повинно відповідати формату Y-m-d\\TH:i:sP."
        ]
    }
}

Припустімо, ми хочемо, щоб повідомлення валідації звучало інакше. Як і в об'єктах запитів Laravel, можна визначити метод messages():

public static function messages(): array
{
    return [
        'published_at.date_format' => 'Часова позначка події повинна бути у форматі ISO 8601 (наприклад, 2025-05-14T19:32:31+00:00).',
    ];
}

Масив повідомлень використовує ті ж шаблони, що й об'єкти запитів Laravel, підтримує вкладені об'єкти та інше. Ось як виглядатиме наше оновлене повідомлення для поля published_at:

{
    "message": "...",
    "errors": {
        "published_at": [
            "Часова позначка події повинна бути у форматі ISO 8601 (наприклад, 2025-05-14T19:32:31+00:00)."
        ]
    }
}

# Дізнайтесь більше

Щоб дізнатися більше про використання валідації з пакетом Laravel Data, ознайомтеся з розділом про розширене використання в Використання атрибутів валідації та сторінкою Атрибути валідації для всіх доступних атрибутів, які можна використовувати у валідації.