Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як задати параметри URL за замовчуванням для локалі чи тенанта і чому важливий пріоритет middleware?

Задача: усі маршрути мають префікс {locale} чи {team}:

Route::prefix('{locale}')->group(function () {
    Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
    Route::get('/posts/{post}', [PostController::class, 'show'])->name('posts.show');
});

Тепер кожен виклик route() вимагає locale: route('posts.show', ['locale' => app()->getLocale(), 'post' => $post]). Забули - виняток Missing required parameter. Посилань сотні.

URL::defaults - значення параметра за замовчуванням на весь запит:

final class SetUrlDefaults
{
    public function handle(Request $request, Closure $next): Response
    {
        URL::defaults(['locale' => $request->route('locale') ?? config('app.locale')]);

        return $next($request);
    }
}

Далі просто route('posts.show', $post) - locale підставиться сам.

Пастка з прив'язкою моделей. Якщо маршрут використовує неявну прив'язку моделей ({post}), middleware SubstituteBindings будує й перевіряє параметри маршруту. Якщо ваш middleware зі значеннями за замовчуванням виконується після нього, прив'язка спрацює раніше, ніж з'являться значення, - і ви отримаєте помилки на кшталт неправильних параметрів. Тому middleware ставлять у пріоритеті перед SubstituteBindings:

->withMiddleware(function (Middleware $middleware): void {
    $middleware->prependToPriorityList(
        before: \Illuminate\Routing\Middleware\SubstituteBindings::class,
        prepend: \App\Http\Middleware\SetUrlDefaults::class,
    );
})

Де ще потрібні значення за замовчуванням:

  • черги, команди, листи - там немає поточного запиту й middleware не виконується. Завдання, яке генерує посилання для листа, має встановити URL::defaults саме (наприклад, з локалі отримувача) - інакше знову Missing required parameter;
  • Octane: значення за замовчуванням зберігаються в генераторі URL між запитами в тому самому воркері, тож middleware має встановлювати їх на кожен запит, а не лише коли значення змінилося;
  • тести: у тестах генерації посилань поза HTTP-запитом значення треба задати явно.

Альтернативи:

  • субдомени ({team}.app.com) - те саме з параметром домену в Route::domain('{team}.example.com');
  • локаль без префікса URL (з налаштувань користувача чи заголовка) - простіше для маршрутів, але гірше для SEO і кешування: одна адреса з різним вмістом.

Докладніше в документації: URL: значення за замовчуванням

Схожі питання