Официальная документация Laravel. Маршрутизация.
Маршрутизация в Laravel. Официальная документация.

Официальная документация Laravel. Маршрутизация.



Базовая маршрутизация

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

use Illuminate\Support\Facades\Route;
 
Route::get('/greeting', function () {
    return 'Всем превед! =D';
});

Файлы маршрутизации по умолчанию

Все маршруты Laravel определяются в файлах маршрутов, которые находятся в каталоге routes. Эти файлы автоматически загружаются провайдером App\Providers\RouteServiceProvider приложения Laravel. В файле routes/web.php определяются маршруты, предназначенные для веб-интерфейса. Этим маршрутам присваивается группа middleware web, которая предоставляет такие возможности, как состояние сессии и защита CSRF. Маршруты в файле routes/api.php не имеют состояния и относятся к группе middleware api.

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

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

Маршруты, определенные в файле routes/api.php, вложены в группу маршрутов провайдера RouteServiceProvider. Внутри этой группы автоматически применяется префикс /api в URI, поэтому нет необходимости вручную указывать его для каждого маршрута в файле. Префикс и другие параметры группы маршрутов можно изменить, модифицировав класс RouteServiceProvider.

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

Маршрутизатор позволяет регистрировать маршруты, отвечающие на любой 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.

Маршруты представлений

Если маршрут должен возвращать только представление (view), то можно использовать метод Route::view. Как и метод redirect, этот метод представляет собой простую возможность, позволяющую обойтись без определения полноценного маршрута или контроллера. Метод view принимает в качестве первого аргумента URI, а в качестве второго - имя представления. Кроме того, в качестве необязательного третьего аргумента можно указать массив данных для передачи в представление:

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

Внимание!
При использовании параметров маршрута в маршрутах представления следующие параметры зарезервированы Laravel и не могут быть использованы: view, data, status и headers.

Список маршрутизации

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

php artisan route:list

По умолчанию middleware, назначенные каждому маршруту, не отображаются в выводе route:list; однако можно указать Laravel на отображение middleware маршрута и имен групп middleware, добавив в команду опцию -v:

php artisan route:list -v
 
# Развернуть группы middleware...
php artisan route:list -vv

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

php artisan route:list --path=api

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

php artisan route:list --except-vendor

Аналогичным образом можно указать Laravel показывать только те маршруты, которые определены сторонними пакетами, задав опцию --only-vendor при выполнении команды route:list:

php artisan route:list --only-vendor

Параметры маршрута

Обязательные параметры маршрута

Иногда требуется определить сегменты URI в маршруте. Например, может потребоваться получить идентификатор пользователя из URL. Это можно сделать, определив параметры маршрута:

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

Можно определить столько параметров маршрута, сколько требуется для его работы:

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

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

Параметры и инъекция зависимостей

Если маршрут имеет зависимости, которые сервис-контейнер Laravel должен автоматически вводить в callback маршрута, то параметры маршрута следует перечислить после зависимостей:

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']);

Если входящий запрос не соответствует ограничениям шаблона маршрута, то будет возвращен HTTP-ответ 404.

Глобальные ограничения

Если требуется, чтобы параметр маршрута всегда ограничивался заданным регулярным выражением, можно воспользоваться методом pattern. Эти паттерны следует определить в методе boot класса App\Providers\RouteServiceProvider:

/**
 * Определите связку маршрута со связанными моделями, паттернами шаблонов и т.д.
 */
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 для экземпляра маршрутизации. Например, можно проверить имя текущего маршрута из middleware маршрута:

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);
}

Группы маршрутов

Группы маршрутов позволяют совместно использовать атрибуты маршрута, такие как 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. Например, вы хотите присвоить всем URI маршрутов в группе префикс admin:

Route::prefix('admin')->group(function () {
    Route::get('/users', function () {
        // Соответствие URL
    });
});

Префиксы имен маршрутов

Метод 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 запроса. Если такой экземпляр в базе данных не найден, то автоматически будет сгенерирован HTTP-ответ 404.

Конечно, неявное связывание возможно и при использовании методов контроллера. Опять же, обратите внимание на то, что {user} в URI сегменте совпадает с переменной $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. Например, рассмотрим такое определение маршрута, которое извлекает записи блога по slug для определенного пользователя:

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();

Настройка поведения отсутствующих моделей

Обычно, если неявно связанная модель не найдена, генерируется HTTP-ответ 404. Однако вы можете настроить это поведение, вызвав метод 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');
        });

Неявное связывание перечислений

В PHP 8.1 появилась поддержка Enum. Чтобы добавить эту возможность, Laravel позволяет вводить строковое перечисление Enum в определение маршрута, и Laravel будет вызывать маршрут только в том случае, если этот сегмент маршрута соответствует правильному значению Enum. В противном случае автоматически будет возвращен HTTP-ответ 404. Например, если задан следующий Enum:

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

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

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

Явное связывание

Для использования привязки моделей к маршрутам не обязательно использовать неявное, основанное на соглашениях распознавание моделей в Laravel. Можно также явно определить, как параметры маршрута соотносятся с моделями. Для регистрации явной привязки используйте метод model маршрутизатора, чтобы указать класс для данного параметра. Явные привязки моделей следует определять в начале метода boot класса RouteServiceProvider:

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 провайдера RouteServiceProvider приложения Laravel:

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" через обработчик исключений приложения Laravel. Однако, поскольку обычно маршрут fallback задается в файле routes/web.php, к нему будет применяться все middleware из группы web middleware. При необходимости к этому маршруту можно добавить дополнительные middleware:

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

Внимание!
Такой резервный fallback маршрут всегда должен быть последним маршрутом, зарегистрированным приложением.

Ограничение скорости

Определение ограничения скорости

В состав Laravel входят мощные и настраиваемые службы ограничения скорости, которые можно использовать для ограничения объема трафика по заданному маршруту или группе маршрутов. Для начала работы необходимо определить конфигурации ограничителей скорости, отвечающие потребностям вашего приложения.

Обычно ограничители скорости определяются в методе boot класса App\Providers\RouteServiceProvider приложения Laravel. Фактически этот класс уже содержит определение ограничителя скорости, которое применяется к маршрутам в файле routes/api.php вашего приложения:

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. Этот класс содержит полезные методы "конструктора", позволяющие быстро определить лимит. Имя ограничителя скорости может быть любой строкой:

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 автоматически возвращает ответ с кодом состояния 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 раз в минуту для аутентифицированного ID пользователя или 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')),
    ];
});

Подключение ограничителей скорости к маршрутам

Ограничители скорости могут быть привязаны к маршрутам или группам маршрутов с помощью middleware throttle. Middleware throttle принимает имя ограничителя скорости, который требуется назначить маршруту:

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

Регулирование скорости с помощью Redis

Обычно middleware throttle связано с классом Illuminate\Routing\Middleware\ThrottleRequests. Эта привязка определяется в ядре HTTP приложения Laravel (App\Http\Kernel). Однако если в качестве кэширующего компонента в приложении используется Redis, то можно изменить это соответствие и использовать класс Illuminate\Routing\Middleware\ThrottleRequestsWithRedis. Этот класс более эффективно управляет ограничением скорости при использовании Redis:

'throttle' => \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,

Подстановка метода обработки формы

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>

Для удобства можно использовать директиву Blade @method для генерации поля ввода _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 может автоматически отвечать на HTTP-запросы CORS при помощи значений OPTIONS, которые можно настроить. Все параметры CORS могут быть настроены в конфигурационном файле config/cors.php приложения Laravel. Обработка запросов OPTIONS будет автоматически осуществляться с помощью middleware HandleCors, которое по умолчанию включено в глобальный стек middleware. Этот глобальный стек middleware находится в ядре HTTP приложения (App\Http\Kernel).

Информация!
Для получения дополнительной информации о CORS и CORS-заголовках обратитесь к документации MDN по CORS.

Кэширование маршрутов

При развертывании приложения в production следует воспользоваться преимуществами кэша маршрутов Laravel. Использование кэша маршрутов позволит значительно сократить время выполнения регистрации всех маршрутов приложения. Чтобы сгенерировать кэш маршрутов, выполните команду route:cache Artisan:

php artisan route:cache

После выполнения этой команды кэшированный файл маршрутов будет загружаться при каждом запросе. Помните, что при добавлении новых маршрутов необходимо будет генерировать новый кэш маршрутов. В связи с этим команду route:cache следует выполнять только во время развертывания проекта в production.

Для очистки кэша маршрутов можно использовать команду route:clear:

php artisan route:clear

Перевод с английского официальной документации Laravel:
https://laravel.com/docs/10.x/routing

Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню