Урок 02

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:

МетодCRUDURLДействие
GETRead/postsСписок
GETRead/posts/5Один
POSTCreate/postsСоздать
PUTUpdate/posts/5Обновить
PATCHUpdate/posts/5Частично
DELETEDelete/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() — проверка.

Дальше — параметры роутов.