- Базовая маршрутизация
- Параметры маршрута
- Именованные маршруты
- Группы маршрутов
- Привязка к модели маршрута
- Резервные маршруты
- Ограничение скорости
- Подстановка метода обработки формы
- Доступ к текущему маршруту
- Совместное использование ресурсов по перекрестным адресам (CORS)
- Кэширование маршрутов
Базовая маршрутизация
Наиболее простые маршруты 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
Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)