Інколи дія потрібна не для того, щоб змінити стан і перемалювати компонент, а щоб отримати дані для JavaScript: варіанти автодоповнення, точки для карти, дані для графіка. Атрибут #[Json] робить дію таким ендпойнтом.
use Livewire\Attributes\Json;
new class extends Component {
#[Json]
public function searchCities(string $query): array
{
return City::query()
->where('name', 'like', "{$query}%")
->limit(10)
->get(['id', 'name'])
->toArray();
}
};
<div x-data="{ query: '', cities: [] }">
<input x-model="query" x-on:input.debounce.300ms="cities = await $wire.searchCities(query)">
<template x-for="city in cities" :key="city.id">
<button type="button" x-text="city.name" x-on:click="$wire.cityId = city.id"></button>
</template>
</div>
Що відрізняє #[Json]-дію:
- повернене значення приходить у JavaScript як результат Promise від
$wire.method(); - помилки валідації не потрапляють у
@error, а відхиляють Promise зі структурою{ status: 422, errors: { поле: [...] } }:
try {
const result = await $wire.save();
} catch (e) {
if (e.status === 422) showErrors(e.errors);
}
- компонент не перерендерюється заради результату - дані живуть в Alpine.
Навіщо це замість окремого API-маршруту:
- не потрібні маршрут, контролер, CSRF-налаштування й автентифікація для API - дія працює в контексті компонента з його станом (
$this->countryId) і поточним користувачем; - логіка лишається поруч із компонентом, який її використовує.
Що варто пам'ятати:
- це публічний ендпойнт: будь-хто з доступом до сторінки може викликати метод з довільними аргументами. Обмежуйте результат (
limit), перевіряйте права, не повертайте зайвих полів моделей (паролі, приховані атрибути -toArray()поважає$hidden, але явнийget(['id', 'name'])надійніший); - частота: debounce на введенні обов'язковий, інакше кожна літера - запит;
- паралельність: такі дії часто поєднують з
#[Async], щоб вони не стояли в черзі за іншими діями компонента. Але тоді результат має зберігатися лише в JavaScript, не у властивостях; - для великих обсягів даних (тисячі точок) варто подумати про окремий кешований ендпойнт - відповідь дії Livewire теж містить знімок стану компонента.