Маршрутизація

Основи Маршрутизації

Найбільш базові маршрути Laravel приймають URI та замикання, забезпечуючи дуже простий і виразний метод визначення маршрутів і поведінки без складних конфігураційних файлів маршрутизації:

use Illuminate\Support\Facades\Route;
 
Route::get('/greeting', function () {
    return 'Hello World';
});

Файли Маршрутів За Замовчуванням

Усі маршрути Laravel визначені у ваших файлах маршрутів, які знаходяться в директорії routes. Ці файли автоматично завантажуються Laravel, використовуючи конфігурацію, зазначену у файлі bootstrap/app.php вашого застосунку. Файл routes/web.php визначає маршрути для вашого веб-інтерфейсу. Ці маршрути призначені для web групи middleware, яка надає такі функції, як стан сесії та захист від CSRF.

Для більшості застосунків ви почнете з визначення маршрутів у вашому файлі routes/web.php. Маршрути, визначені в routes/web.php, можуть бути доступні шляхом введення URL визначеного маршруту у вашому браузері. Наприклад, ви можете отримати доступ до наступного маршруту, перейшовши за адресою http://example.com/user у вашому браузері:

use App\Http\Controllers\UserController;
 
Route::get('/user', [UserController::class, 'index']);

Маршрути API

Якщо ваш застосунок також пропонуватиме безстан API, ви можете увімкнути маршрутизацію API за допомогою команди Artisan install:api:

php artisan install:api

Команда install:api встановлює Laravel Sanctum, який надає надійний, але простий механізм аутентифікації API токенів, що може бути використаний для аутентифікації сторонніх API споживачів, SPA або мобільних застосунків. Крім того, команда install:api створює файл routes/api.php:

Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');

Маршрути в routes/api.php є безстанними і призначені до api групи проміжного програмного забезпечення. Крім того, префікс URI /api автоматично застосовується до цих маршрутів, тому вам не потрібно вручну застосовувати його до кожного маршруту у файлі. Ви можете змінити префікс, змінивши файл bootstrap/app.php вашого застосунку:

->withRouting(
    api: __DIR__.'/../routes/api.php',
    apiPrefix: 'api/admin',
    // ...
)

Доступні методи маршрутизатора

Маршрутизатор дозволяє реєструвати маршрути, які відповідають на будь-яке HTTP-дієслово:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Іноді вам може знадобитися зареєструвати маршрут, який відповідає на кілька HTTP-дієслів. Ви можете зробити це, використовуючи метод match. Або, ви навіть можете зареєструвати маршрут, який відповідає на всі HTTP-дієслова, використовуючи метод any:

Route::match(['get', 'post'], '/', function () {
    // ...
});
 
Route::any('/', function () {
    // ...
});

Коли визначаються декілька маршрутів, які мають однаковий URI, маршрути, що використовують методи get, post, put, patch, delete та options, повинні бути визначені перед маршрутами, що використовують методи any, match та redirect. Це забезпечує відповідність вхідного запиту з правильним маршрутом.

Ін'єкція залежностей

Ви можете вказати тип будь-яких залежностей, необхідних для вашого маршруту, у сигнатурі зворотного виклику вашого маршруту. Оголошені залежності будуть автоматично вирішені та впроваджені у зворотний виклик за допомогою Laravel сервіс-контейнера. Наприклад, ви можете вказати тип класу Illuminate\Http\Request, щоб поточний HTTP-запит автоматично впроваджувався у зворотний виклик вашого маршруту:

use Illuminate\Http\Request;
 
Route::get('/users', function (Request $request) {
    // ...
});

Захист від CSRF

Пам'ятайте, що будь-які HTML форми, які вказують на маршрути POST, PUT, PATCH або DELETE, які визначені у файлі маршрутів web, повинні включати поле з CSRF токеном. В іншому випадку запит буде відхилено. Ви можете дізнатися більше про захист CSRF у документації CSRF:

<form method="POST" action="/profile">
    @csrf
    ...
</form>

Маршрути Перенаправлення

Якщо ви визначаєте маршрут, який перенаправляє на інший URI, ви можете використовувати метод Route::redirect. Цей метод надає зручний ярлик, щоб вам не довелося визначати повний маршрут або контролер для виконання простого перенаправлення:

Route::redirect('/here', '/there');

За замовчуванням, Route::redirect повертає код статусу 302. Ви можете налаштувати код статусу, використовуючи необов'язковий третій параметр:

Route::redirect('/here', '/there', 301);

Або ви можете використовувати метод Route::permanentRedirect, щоб повернути статус-код 301:

Route::permanentRedirect('/here', '/there');

При використанні параметрів маршруту в маршрутах перенаправлення, наступні параметри зарезервовані Laravel і не можуть бути використані: destination і status.

Представлення Маршрутів

Якщо ваш маршрут лише повинен повертати представлення, ви можете використовувати метод Route::view. Як і метод redirect, цей метод надає простий ярлик, щоб вам не довелося визначати повний маршрут або контролер. Метод view приймає URI як перший аргумент і ім'я представлення як другий аргумент. Крім того, ви можете надати масив даних для передачі в представлення як необов'язковий третій аргумент:

Route::view('/welcome', 'welcome');
 
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

Коли використовуються параметри маршруту у маршрутах перегляду, наступні параметри зарезервовані Laravel і не можуть бути використані: view, data, status і headers.

Перелік Ваших Маршрутів

Команда Artisan route:list може легко надати огляд усіх маршрутів, які визначені вашим застосунком:

php artisan route:list

За замовчуванням, проміжне програмне забезпечення маршруту, яке призначено кожному маршруту, не буде відображено у виводі route:list; однак, ви можете вказати Laravel відобразити проміжне програмне забезпечення маршруту та імена груп проміжного програмного забезпечення, додавши опцію -v до команди:

php artisan route:list -v
 
# Розгорнути групи middleware...
php artisan route:list -vv

Ви також можете вказати Laravel показувати лише маршрути, які починаються з заданого URI:

php artisan route:list --path=api

Крім того, ви можете вказати Laravel приховати будь-які маршрути, які визначені сторонніми пакетами, надавши опцію --except-vendor при виконанні команди route:list:

php artisan route:list --except-vendor

Так само, ви можете вказати Laravel показувати лише маршрути, які визначені сторонніми пакетами, надавши опцію --only-vendor при виконанні команди route:list:

php artisan route:list --only-vendor

Налаштування Маршрутизації

За замовчуванням маршрути вашого застосунку налаштовані та завантажуються файлом bootstrap/app.php:

<?php
 
use Illuminate\Foundation\Application;
 
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )->create();

Однак іноді ви можете захотіти визначити абсолютно новий файл для зберігання підмножини маршрутів вашого застосунку. Щоб досягти цього, ви можете надати замикання then методу withRouting. У цьому замиканні ви можете зареєструвати будь-які додаткові маршрути, які необхідні для вашого застосунку:

use Illuminate\Support\Facades\Route;
 
->withRouting(
    web: __DIR__.'/../routes/web.php',
    commands: __DIR__.'/../routes/console.php',
    health: '/up',
    then: function () {
        Route::middleware('api')
            ->prefix('webhooks')
            ->name('webhooks.')
            ->group(base_path('routes/webhooks.php'));
    },
)

Або ви можете навіть взяти повний контроль над реєстрацією маршрутів, надаючи замикання using методу withRouting. Коли цей аргумент передається, жодні HTTP-маршрути не будуть зареєстровані фреймворком, і ви несете відповідальність за ручну реєстрацію всіх маршрутів:

use Illuminate\Support\Facades\Route;
 
->withRouting(
    commands: __DIR__.'/../routes/console.php',
    using: function () {
        Route::middleware('api')
            ->prefix('api')
            ->group(base_path('routes/api.php'));
 
        Route::middleware('web')
            ->group(base_path('routes/web.php'));
    },
)

Параметри Маршруту

Обов'язкові параметри

Іноді вам потрібно буде захопити сегменти URI у вашому маршруті. Наприклад, вам може знадобитися захопити ID користувача з URL. Ви можете зробити це, визначивши параметри маршруту:

Route::get('/user/{id}', function (string $id) {
    return 'User '.$id;
});

Ви можете визначити стільки параметрів маршруту, скільки потрібно для вашого маршруту:

Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
    // ...
});

Параметри маршруту завжди обрамлені в дужки {} і повинні складатися з алфавітних символів. Підкреслення (_) також допустимі в іменах параметрів маршруту. Параметри маршруту впроваджуються в зворотні виклики маршруту / контролери на основі їх порядку - імена аргументів зворотного виклику маршруту / контролера не мають значення.

Параметри та Впровадження Залежностей

Якщо ваш маршрут має залежності, які ви хочете, щоб Сервіс-контейнер Laravel автоматично впроваджував у зворотний виклик вашого маршруту, ви повинні перерахувати параметри маршруту після ваших залежностей:

use Illuminate\Http\Request;
 
Route::get('/user/{id}', function (Request $request, string $id) {
    return 'User '.$id;
});

Опціональні параметри

Іноді вам може знадобитися вказати параметр маршруту, який може не завжди бути присутнім в URI. Ви можете зробити це, поставивши знак ? після імені параметра. Переконайтеся, що змінній, що відповідає маршруту, задано значення за замовчуванням:

Route::get('/user/{name?}', function (?string $name = null) {
    return $name;
});
 
Route::get('/user/{name?}', function (?string $name = 'John') {
    return $name;
});

Регулярні вирази обмеження

Ви можете обмежити формат параметрів вашого маршруту, використовуючи метод where на екземплярі маршруту. Метод where приймає ім'я параметра та регулярний вираз, що визначає, як параметр повинен бути обмежений:

Route::get('/user/{name}', function (string $name) {
    // ...
})->where('name', '[A-Za-z]+');
 
Route::get('/user/{id}', function (string $id) {
    // ...
})->where('id', '[0-9]+');
 
Route::get('/user/{id}/{name}', function (string $id, string $name) {
    // ...
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

Для зручності деякі часто використовувані шаблони регулярних виразів мають допоміжні методи, які дозволяють швидко додавати обмеження шаблону до ваших маршрутів:

Route::get('/user/{id}/{name}', function (string $id, string $name) {
    // ...
})->whereNumber('id')->whereAlpha('name');
 
Route::get('/user/{name}', function (string $name) {
    // ...
})->whereAlphaNumeric('name');
 
Route::get('/user/{id}', function (string $id) {
    // ...
})->whereUuid('id');
 
Route::get('/user/{id}', function (string $id) {
    // ...
})->whereUlid('id');
 
Route::get('/category/{category}', function (string $category) {
    // ...
})->whereIn('category', ['movie', 'song', 'painting']);
 
Route::get('/category/{category}', function (string $category) {
    // ...
})->whereIn('category', CategoryEnum::cases());

Якщо вхідний запит не відповідає обмеженням шаблону маршруту, буде повернуто HTTP-відповідь 404.

Глобальні Обмеження

Якщо ви хочете, щоб параметр маршруту завжди обмежувався заданим регулярним виразом, ви можете використовувати метод pattern. Ви повинні визначити ці шаблони в методі boot класу App\Providers\AppServiceProvider вашого застосунку:

use Illuminate\Support\Facades\Route;
 
/**
* Ініціалізуйте будь-які сервіси застосунку.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}

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

Route::get('/user/{id}', function (string $id) {
// Виконується лише якщо {id} є числовим...
});

Закодовані косі риски

Компонент маршрутизації Laravel дозволяє всі символи, окрім /, бути присутніми в значеннях параметрів маршруту. Ви повинні явно дозволити / бути частиною вашого заповнювача, використовуючи регулярний вираз умови where:

Route::get('/search/{search}', function (string $search) {
    return $search;
})->where('search', '.*');

Кодовані косі риски підтримуються лише в останньому сегменті маршруту.

Іменовані маршрути

Іменовані маршрути дозволяють зручно генерувати URL-адреси або перенаправлення для конкретних маршрутів. Ви можете вказати ім'я для маршруту, додавши метод name до визначення маршруту:

Route::get('/user/profile', function () {
    // ...
})->name('profile');

Ви також можете вказати імена маршрутів для дій контролера:

Route::get(
    '/user/profile',
    [UserProfileController::class, 'show']
)->name('profile');

Імена маршрутів завжди повинні бути унікальними.

Генерація URL-адрес до іменованих маршрутів

Після того як ви призначили ім'я для заданого маршруту, ви можете використовувати ім'я маршруту при генерації URL-адрес або перенаправлень за допомогою допоміжних функцій Laravel route та redirect:

// Генерування URL-адрес...
$url = route('profile');
 
// Генерування перенаправлень...
return redirect()->route('profile');
 
return to_route('profile');

Якщо іменований маршрут визначає параметри, ви можете передати параметри як другий аргумент у функцію route. Задані параметри будуть автоматично вставлені в згенерований URL у їхніх правильних позиціях:

Route::get('/user/{id}/profile', function (string $id) {
    // ...
})->name('profile');
 
$url = route('profile', ['id' => 1]);

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

Route::get('/user/{id}/profile', function (string $id) {
    // ...
})->name('profile');
 
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
 
// /user/1/profile?photos=yes

Іноді ви можете захотіти вказати значення за замовчуванням для параметрів URL на рівні всього запиту, таких як поточна локаль. Щоб досягти цього, ви можете використовувати метод URL::defaults.

Інспектування поточного маршруту

Якщо ви хочете визначити, чи був поточний запит спрямований на заданий іменований маршрут, ви можете використовувати метод named на екземплярі Route. Наприклад, ви можете перевірити ім'я поточного маршруту з проміжного програмного забезпечення маршруту:

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
/**
* Обробити вхідний запит.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->route()->named('profile')) {
// ...
}
 
return $next($request);
}

Групи Маршрутів

Route групи дозволяють ділитися атрибутами маршруту, такими як middleware, для великої кількості маршрутів без необхідності визначати ці атрибути для кожного окремого маршруту.

Вкладені групи намагаються розумно «об’єднати» атрибути з батьківською групою. Middleware та умови where об’єднуються, тоді як імена та префікси доповнюються. Роздільники просторів імен та слеші в префіксах URI автоматично додаються там, де це доречно.

Middleware

Щоб призначити middleware для всіх маршрутів у групі, ви можете використовувати метод middleware перед визначенням групи. Middleware виконуються в порядку, в якому вони перераховані в масиві:

Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Використовує first & second middleware...
});
 
Route::get('/user/profile', function () {
// Використовує first & second middleware...
});
});

Контролери

Якщо група маршрутів всі використовують один і той самий контролер, ви можете використовувати метод controller для визначення спільного контролера для всіх маршрутів у групі. Потім, при визначенні маршрутів, вам потрібно лише вказати метод контролера, який вони викликають:

use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});

Маршрутизація піддоменів

Маршрутні групи також можуть бути використані для обробки маршрутизації піддоменів. Піддомени можуть бути призначені параметрами маршруту так само, як і URI маршруту, що дозволяє захопити частину піддомену для використання у вашому маршруті або контролері. Піддомен може бути вказаний шляхом виклику методу domain перед визначенням групи:

Route::domain('{account}.example.com')->group(function () {
    Route::get('/user/{id}', function (string $account, string $id) {
        // ...
    });
});

Щоб забезпечити доступність маршрутів піддомену, слід реєструвати маршрути піддомену перед реєстрацією маршрутів кореневого домену. Це запобігатиме перезапису маршрутів піддомену маршрутами кореневого домену, які мають той самий шлях URI.

Префікси Маршрутів

Метод prefix може бути використаний для додавання префіксу до кожного маршруту в групі з вказаним URI. Наприклад, ви можете захотіти додати префікс admin до всіх URI маршрутів у групі:

Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Відповідає URL-адресі "/admin/users"
});
});

Префікси Імен Маршрутів

Метод name може бути використаний для додавання префікса до кожної назви маршруту в групі з заданим рядком. Наприклад, ви можете захотіти додати префікс admin до назв усіх маршрутів у групі. Заданий рядок додається до назви маршруту точно так, як він вказаний, тому ми повинні забезпечити наявність кінцевого символу . у префіксі:

Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Маршруту призначено ім’я "admin.users"...
})->name('users');
});

Маршрутне Зв'язування Моделей

Коли ви передаєте ID моделі в маршрут або дію контролера, ви часто будете виконувати запит до бази даних, щоб отримати модель, яка відповідає цьому ID. Прив'язка моделі маршруту в Laravel надає зручний спосіб автоматично передавати екземпляри моделей безпосередньо у ваші маршрути. Наприклад, замість того, щоб передавати ID користувача, ви можете передати весь екземпляр моделі User, який відповідає заданому ID.

Імпліцитне Зв'язування

Laravel автоматично вирішує моделі Eloquent, визначені в маршрутах або діях контролера, чиї імена змінних з підказкою типу відповідають імені сегмента маршруту. Наприклад:

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
    return $user->email;
});

Оскільки змінна $user має типізацію як Eloquent модель App\Models\User і назва змінної відповідає сегменту URI {user}, Laravel автоматично інжектує екземпляр моделі, ID якого відповідає значенню з URI запиту. Якщо відповідний екземпляр моделі не знайдено в базі даних, автоматично буде згенеровано 404 HTTP відповідь.

Звичайно, неявне зв'язування також можливе при використанні методів контролера. Знову ж таки, зверніть увагу, що сегмент URI {user} відповідає змінній $user у контролері, яка містить підказку типу App\Models\User:

use App\Http\Controllers\UserController;
use App\Models\User;
 
// Визначення маршруту...
Route::get('/users/{user}', [UserController::class, 'show']);
 
// Визначення методу контролера...
public function show(User $user)
{
return view('user.profile', ['user' => $user]);
}

М'яко Видалені Моделі

Зазвичай, неявне зв'язування моделей не буде отримувати моделі, які були м'яко видалені. Однак, ви можете вказати неявному зв'язуванню отримувати ці моделі, додавши метод withTrashed до визначення вашого маршруту:

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
    return $user->email;
})->withTrashed();

Налаштування Ключа

Іноді ви можете захотіти вирішити моделі Eloquent, використовуючи стовпець, відмінний від id. Для цього ви можете вказати стовпець у визначенні параметра маршруту:

use App\Models\Post;
 
Route::get('/posts/{post:slug}', function (Post $post) {
    return $post;
});

Якщо ви хочете, щоб прив'язка моделі завжди використовувала інший стовпець бази даних, ніж id, при отриманні даного класу моделі, ви можете перевизначити метод getRouteKeyName у моделі Eloquent:

/**
* Отримати ключ маршруту для моделі.
*/
public function getRouteKeyName(): string
{
return 'slug';
}

Користувацькі ключі та обмеження області видимості

Коли ви неявно зв'язуєте кілька моделей Eloquent в одному визначенні маршруту, ви можете захотіти обмежити другу модель Eloquent так, щоб вона була дочірньою до попередньої моделі Eloquent. Наприклад, розгляньте це визначення маршруту, яке отримує блог-пост за сликом для конкретного користувача:

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

Коли використовується користувацьке ключове неявне зв'язування як вкладений параметр маршруту, Laravel автоматично обмежить запит для отримання вкладеної моделі за її батьком, використовуючи конвенції для вгадування імені відношення на батькові. У цьому випадку буде припущено, що модель User має відношення з назвою posts (множинна форма імені параметра маршруту), яке можна використовувати для отримання моделі Post.

Якщо ви бажаєте, ви можете вказати Laravel обмежити "дочірні" зв'язки, навіть коли користувацький ключ не надано. Для цього ви можете викликати метод scopeBindings при визначенні вашого маршруту:

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    return $post;
})->scopeBindings();

Або ви можете вказати цілій групі визначень маршрутів використовувати прив'язки з областю:

Route::scopeBindings()->group(function () {
    Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
        return $post;
    });
});

Аналогічно, ви можете явно вказати Laravel не обмежувати прив'язки, викликавши метод withoutScopedBindings:

Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
})->withoutScopedBindings();

Налаштування поведінки відсутньої моделі

Зазвичай, буде згенеровано 404 HTTP-відповідь, якщо не знайдено модель, що зв'язується неявно. Однак, ви можете налаштувати цю поведінку, викликавши метод missing при визначенні вашого маршруту. Метод missing приймає замикання, яке буде викликано, якщо не вдасться знайти модель, що зв'язується неявно:

use App\Http\Controllers\LocationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
 
Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
    ->name('locations.view')
    ->missing(function (Request $request) {
        return Redirect::route('locations.index');
    });

Неявне Зв'язування Enum

У PHP 8.1 було додано підтримку перерахувань (Enum). На додаток до цієї можливості Laravel дозволяє використовувати типізацію перерахування, яке має строкове значення (string-backed Enum), у визначенні маршруту. Laravel викличе маршрут лише в тому разі, якщо відповідний сегмент маршруту відповідає допустимому значенню Enum. Інакше автоматично буде повернуто відповідь 404 HTTP. Наприклад, маємо таке Enum:

<?php
 
namespace App\Enums;
 
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}

Ви можете визначити маршрут, який буде викликаний лише якщо сегмент маршруту {category} є fruits або people. В іншому випадку, Laravel поверне 404 HTTP-відповідь:

use App\Enums\Category;
use Illuminate\Support\Facades\Route;
 
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});

Явне Зв'язування

Ви не зобов'язані використовувати імпліцитне, засноване на конвенціях, розв'язання моделей Laravel для використання прив'язки моделей. Ви також можете явно визначити, як параметри маршруту відповідають моделям. Щоб зареєструвати явну прив'язку, використовуйте метод маршрутизатора model, щоб вказати клас для заданого параметра. Ви повинні визначити ваші явні прив'язки моделей на початку методу boot вашого класу AppServiceProvider:

use App\Models\User;
use Illuminate\Support\Facades\Route;
 
/**
* Ініціалізуйте будь-які сервіси застосунку.
*/
public function boot(): void
{
Route::model('user', User::class);
}

Далі, визначте маршрут, що містить параметр {user}:

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
    // ...
});

Оскільки ми зв'язали всі параметри {user} з моделлю App\Models\User, екземпляр цього класу буде ін'єктовано в маршрут. Отже, наприклад, запит до users/1 ін'єктує екземпляр User з бази даних, який має ID 1.

Якщо відповідний екземпляр моделі не знайдено в базі даних, автоматично буде згенеровано HTTP-відповідь 404.

Налаштування логіки зв’язування

Якщо ви бажаєте визначити власну логіку вирішення прив'язки моделі, ви можете використовувати метод Route::bind. Замикання, яке ви передаєте методу bind, отримає значення сегмента URI і повинно повернути екземпляр класу, який має бути впроваджений у маршрут. Знову ж таки, ця кастомізація повинна відбуватися в методі boot AppServiceProvider вашого застосунку:

use App\Models\User;
use Illuminate\Support\Facades\Route;
 
/**
* Ініціалізуйте будь-які сервіси застосунку.
*/
public function boot(): void
{
Route::bind('user', function (string $value) {
return User::where('name', $value)->firstOrFail();
});
}

Альтернативно, ви можете перевизначити метод resolveRouteBinding у вашій Eloquent моделі. Цей метод отримає значення сегмента URI і повинен повернути екземпляр класу, який має бути впроваджений у маршрут:

/**
* Отримати модель для прив’язаного значення.
*
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value, $field = null)
{
return $this->where('name', $value)->firstOrFail();
}

Якщо маршрут використовує неявне зв'язування з обмеженням, метод resolveChildRouteBinding буде використовуватися для вирішення дочірнього зв'язування батьківської моделі:

/**
* Отримати дочірню модель для прив’язаного значення.
*
* @param string $childType
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveChildRouteBinding($childType, $value, $field)
{
return parent::resolveChildRouteBinding($childType, $value, $field);
}

Резервні маршрути

Використовуючи метод Route::fallback, ви можете визначити маршрут, який буде виконано, коли жоден інший маршрут не відповідає вхідному запиту. Зазвичай необроблені запити автоматично відображатимуть сторінку "404" через обробник винятків вашого застосунку. Однак, оскільки ви зазвичай визначаєте маршрут fallback у файлі routes/web.php, всі проміжні програмні засоби з групи проміжних програм web будуть застосовані до маршруту. Ви можете вільно додавати додаткові проміжні програмні засоби до цього маршруту за потреби:

Route::fallback(function () {
    // ...
});

Обмеження частоти запитів

Визначення Обмежувачів Частоти Запитів

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

Обмежувачі частоти запитів можуть бути визначені в методі boot класу App\Providers\AppServiceProvider вашого застосунку:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
 
/**
* Ініціалізуйте будь-які сервіси застосунку.
*/
protected function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}

Обмежувачі частоти запитів визначаються за допомогою методу for фасаду RateLimiter. Метод for приймає ім'я обмежувача частоти запитів і замикання, яке повертає конфігурацію обмеження, що має застосовуватися до маршрутів, призначених для цього обмежувача частоти запитів. Конфігурації обмежень є екземплярами класу Illuminate\Cache\RateLimiting\Limit. Цей клас містить корисні методи "builder", щоб ви могли швидко визначити своє обмеження. Ім'я обмежувача частоти запитів може бути будь-яким рядком, який ви бажаєте:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
 
/**
* Ініціалізуйте будь-які сервіси застосунку.
*/
protected function boot(): void
{
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
}

Якщо вхідний запит перевищує вказане обмеження частоти запитів, Laravel автоматично поверне відповідь з кодом статусу HTTP 429. Якщо ви хочете визначити власну відповідь, яка повинна бути повернена при обмеженні частоти запитів, ви можете використовувати метод response:

RateLimiter::for('global', function (Request $request) {
    return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
        return response('Custom response...', 429, $headers);
    });
});

Оскільки зворотні виклики обмежувача частоти запитів отримують вхідний екземпляр HTTP-запиту, ви можете динамічно створити відповідне обмеження частоти запитів на основі вхідного запиту або автентифікованого користувача:

RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
        ? Limit::none()
        : Limit::perMinute(100);
});

Сегментація Обмеження частоти запитів

Іноді ви можете захотіти сегментувати обмеження частоти запитів за деяким довільним значенням. Наприклад, ви можете захотіти дозволити користувачам доступ до певного маршруту 100 разів на хвилину для кожної IP-адреси. Щоб досягти цього, ви можете використовувати метод by при побудові вашого обмеження частоти запитів:

RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
        ? Limit::none()
        : Limit::perMinute(100)->by($request->ip());
});

Щоб проілюструвати цю функцію на іншому прикладі, ми можемо обмежити доступ до маршруту до 100 разів на хвилину для кожного автентифікованого ідентифікатора користувача або 10 разів на хвилину для IP-адреси гостей:

RateLimiter::for('uploads', function (Request $request) {
    return $request->user()
        ? Limit::perMinute(100)->by($request->user()->id)
        : Limit::perMinute(10)->by($request->ip());
});

Кілька Обмежень частоти запитів

Якщо потрібно, ви можете повернути масив обмежень для заданої конфігурації обмежувача частоти запитів. Кожне обмеження  буде оцінюватися для маршруту на основі порядку, в якому вони розміщені в масиві:

RateLimiter::for('login', function (Request $request) {
    return [
        Limit::perMinute(500),
        Limit::perMinute(3)->by($request->input('email')),
    ];
});

Якщо ви призначаєте кілька обмежень, сегментованих за однаковими значеннями by, ви повинні переконатися, що кожне значення by є унікальним. Найпростіший спосіб досягти цього - додати префікс до значень, наданих методу by:

RateLimiter::for('uploads', function (Request $request) {
    return [
        Limit::perMinute(10)->by('minute:'.$request->user()->id),
        Limit::perDay(1000)->by('day:'.$request->user()->id),
    ];
});

Прикріплення обмежувачів частоти запитів до маршрутів

Ліміти запитів можуть бути прикріплені до маршрутів або груп маршрутів за допомогою throttle middleware. Middleware throttle приймає ім'я ліміту, який ви хочете призначити маршруту:

Route::middleware(['throttle:uploads'])->group(function () {
    Route::post('/audio', function () {
        // ...
    });
 
    Route::post('/video', function () {
        // ...
    });
});

Обмеження з Redis

За замовчуванням, middleware throttle відображається на клас Illuminate\Routing\Middleware\ThrottleRequests. Однак, якщо ви використовуєте Redis як драйвер кешу вашого застосунку, ви можете захотіти вказати Laravel використовувати Redis для управління Обмеженням частоти запитів. Для цього, ви повинні використовувати метод throttleWithRedis у файлі bootstrap/app.php вашого застосунку. Цей метод відображає middleware throttle на клас middleware Illuminate\Routing\Middleware\ThrottleRequestsWithRedis:

->withMiddleware(function (Middleware $middleware) {
    $middleware->throttleWithRedis();
    // ...
})

Підміна методу форми

HTML форми не підтримують дії PUT, PATCH або DELETE. Тому, при визначенні маршрутів PUT, PATCH або DELETE, які викликаються з HTML форми, вам потрібно додати приховане поле _method до форми. Значення, надіслане з полем _method, буде використано як метод HTTP-запиту:

<form action="/example" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

Для зручності, ви можете використовувати директиву @method Blade для генерації поля вводу _method:

<form action="/example" method="POST">
    @method('PUT')
    @csrf
</form>

Доступ до поточного маршруту

Ви можете використовувати методи current, currentRouteName та currentRouteAction на фасаді Route для доступу до інформації про маршрут, що обробляє вхідний запит:

use Illuminate\Support\Facades\Route;
 
$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string

Ви можете звернутися до документації API як для базового класу фасаду Route, так і для екземпляра Route, щоб переглянути всі методи, доступні в класах маршрутизатора та маршруту.

Крос-доменний обмін ресурсами (CORS)

Laravel може автоматично відповідати на CORS OPTIONS HTTP-запити з значеннями, які ви налаштовуєте. Запити OPTIONS будуть автоматично оброблятися HandleCors проміжним програмним забезпеченням, яке автоматично включено в глобальний стек проміжного програмного забезпечення вашого застосунку.

Іноді вам може знадобитися налаштувати значення конфігурації CORS для вашого застосунку. Ви можете зробити це, опублікувавши файл конфігурації cors за допомогою команди Artisan config:publish:

php artisan config:publish cors

Ця команда розмістить файл конфігурації cors.php у директорії config вашого застосунку.

Для отримання додаткової інформації про CORS та заголовки CORS, будь ласка, зверніться до веб-документації MDN про CORS.

Кешування Маршрутів

Коли ви розгортаєте ваш застосунок у продакшн, ви повинні скористатися кешем маршрутів Laravel. Використання кешу маршрутів значно зменшить час, необхідний для реєстрації всіх маршрутів вашого застосунку. Щоб згенерувати кеш маршрутів, виконайте команду Artisan route:cache:

php artisan route:cache

Після виконання цієї команди ваш файл кешованих маршрутів буде завантажуватися при кожному запиті. Пам'ятайте, якщо ви додасте нові маршрути, вам потрібно буде згенерувати новий кеш маршрутів. Через це, ви повинні виконувати команду route:cache лише під час розгортання вашого проєкту.

Ви можете використовувати команду route:clear для очищення кешу маршрутів:

php artisan route:clear