HTTP-методы в роутинге
Что такое HTTP-метод
HTTP-метод — тип действия над ресурсом. Определяет что делать.
Основные методы
| Метод | Действие | Пример |
|---|---|---|
| GET | Читать | Список постов |
| POST | Создать | Новый пост |
| PUT | Обновить целиком | Пост полностью |
| PATCH | Обновить часть | Только заголовок |
| DELETE | Удалить | Удалить пост |
| OPTIONS | Узнать доступные методы | CORS preflight |
| HEAD | Как GET, но без тела | Проверка доступности |
Регистрация
Route::get('/posts', fn () => 'Список');
Route::post('/posts', fn () => 'Создание');
Route::put('/posts/{id}', fn ($id) => "Обновление {$id}");
Route::patch('/posts/{id}', fn ($id) => "Частичное {$id}");
Route::delete('/posts/{id}', fn ($id) => "Удаление {$id}");
Route::options('/posts', fn () => response()->noContent());
Каждый метод — свой статический метод фасада.
match — несколько методов
Route::match(['get', 'post'], '/form', function () {
// обрабатывает GET и POST
});
Когда: форма сама себя отображает и обрабатывает.
any — любой метод
Route::any('/webhook', function () {
// любой HTTP-метод
});
Когда: вебхук, где метод не важен.
⚠️ Осторожно: теряется контроль.
REST и CRUD
REST сопоставляет методы и CRUD:
| Метод | CRUD | URL | Действие |
|---|---|---|---|
| GET | Read | /posts | Список |
| GET | Read | /posts/5 | Один |
| POST | Create | /posts | Создать |
| PUT | Update | /posts/5 | Обновить |
| PATCH | Update | /posts/5 | Частично |
| DELETE | Delete | /posts/5 | Удалить |
Это основа Route::resource.
PUT vs PATCH
PUT — замена всего ресурса.
PUT /posts/5
{ "title": "Новый", "body": "Новый" }
Ожидается: все поля. Отсутствующие → NULL.
PATCH — обновление части.
PATCH /posts/5
{ "title": "Новый" }
Ожидается: только изменённые поля.
В Laravel обычно PATCH — практичнее. Route::resource создаёт оба.
HTML-формы и методы
⚠️ HTML-формы поддерживают только GET и POST.
Решение: скрытое поле _method.
<form method="POST" action="/posts/5">
@csrf
@method('PUT')
<!-- поля -->
</form>
@method('PUT') создаёт:
<input type="hidden" name="_method" value="PUT">
Laravel читает _method и обрабатывает как PUT.
Доступные методы для @method:
- PUT
- PATCH
- DELETE
Spoofing
Laravel принимает _method только от POST-запросов.
GET с _method=DELETE не сработает — защита.
Проверка метода
В контроллере:
if ($request->isMethod('post')) { }
if ($request->isMethod('get')) { }
// Или
if ($request->method() === 'POST') { }
Через Route:
use Illuminate\Support\Facades\Route;
if (Route::is('posts.*')) { }
OPTIONS и CORS
OPTIONS — preflight-запрос от браузера.
Laravel автоматически отвечает на OPTIONS при CORS.
Вручную:
Route::options('/api/posts', function () {
return response()->noContent()
->header('Access-Control-Allow-Origin', '*');
});
Обычно не нужно — config/cors.php.
HEAD
HEAD — как GET, но без тела. Laravel отвечает автоматически.
Когда: проверить, что URL жив, без скачивания данных.
Продвинутое: свои методы
Laravel позволяет добавить свой метод:
// в bootstrap/app.php
Route::macro('purge', function ($uri, $action) {
return Route::match(['purge', 'delete'], $uri, $action);
});
Нестандартно — не делай без нужды.
Практика: REST API
// routes/api.php
Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts', [PostController::class, 'store']);
Route::get('/posts/{post}', [PostController::class, 'show']);
Route::put('/posts/{post}', [PostController::class, 'update']);
Route::patch('/posts/{post}', [PostController::class, 'updatePartial']);
Route::delete('/posts/{post}', [PostController::class, 'destroy']);
Проверь:
php artisan route:list --path=api/posts
Тест:
curl http://localhost:8000/api/posts
curl -X POST http://localhost:8000/api/posts
curl -X DELETE http://localhost:8000/api/posts/1
Частые ошибки
1. Использовать GET для изменений:
Route::get('/posts/{id}/delete', ...); // ❌ плохо
Route::delete('/posts/{id}', ...); // ✅ REST
2. Забыли @method:
<form method="POST" action="/posts/5">
{{-- нет @method('PUT') — обработается как POST --}}
</form>
3. Route::any для админки:
Route::any('/admin', ...); // любой может удалить через GET
4. PUT с частичными данными:
PUT /posts/5 { "title": "X" }
// body = null
Решение: PATCH.
5. _method в GET:
GET /posts/5?_method=DELETE // не сработает
Итог
- GET — читать, POST — создавать, PUT — обновлять целиком, PATCH — частично, DELETE — удалять.
Route::get,post,put,patch,delete.match— несколько,any— все.- HTML-формы — только GET/POST, остальное через
@method. - REST — метод = действие.
$request->isMethod()— проверка.
Дальше — параметры роутов.