Skip to content

Глава 2.5: Маршруты API

Время изучения: 45 минут


1. Что такое маршрут? Объяснение на пальцах

Представьте, что ваш контроллер (PlanetController) — это большой офисный центр, а каждый его метод (index, store, show) — это отдел, выполняющий свою работу.

Маршрут (Route) — это адресная табличка на входе в здание. Она говорит:

  • "Если кто-то пришел по адресу /planets методом GET — отправьте его в отдел index (показать всё)".
  • "Если кто-то пришел по адресу /planets методом POST с посылкой (данными) — отправьте его в отдел store (создать новое)".

Без маршрутов ни один запрос из внешнего мира не найдет нужный ему отдел в вашем коде. Основной файл для таких "адресных табличек" в API — это routes/api.php.

В Laravel 11+ по умолчанию нет "API-адресной книги". Мы создали ее сами, выполнив команду php artisan install:api. Теперь у нас есть файл routes/api.php — это главный центр управления всеми маршрутами нашего API.

Ключевое отличие api.php от web.php:

  • Префикс /api: Laravel автоматически добавляет /api ко всем URL-адресам из этого файла. Маршрут /planets превращается в /api/planets.
  • "Без состояния" (Stateless): Здесь нет сессий и cookie-файлов, как в обычном вебе. Каждый запрос независим и должен содержать в себе всю информацию для аутентификации (обычно это API-токен в заголовках).

2. Путь новичка: Создание маршрута вручную

Давайте создадим один-единственный маршрут своими руками, чтобы понять принцип. Наша цель — заставить URL /api/planets показывать список всех планет.

Откройте routes/api.php и напишите:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PlanetController; // Указываем, где наш контроллер

//                    (1)           (2)                     (3)
Route::get(      '/planets',    [PlanetController::class, 'index']     );
//   ^               ^                       ^
// (HTTP-метод)   (URL-адрес)          (Какой контроллер и метод вызвать)

Разберем эту строку по частям:

  1. Route::get(...) — мы говорим: "Этот маршрут работает только для GET-запросов".
  2. '/planets' — это URL, который будет слушать Laravel. С учетом префикса /api, полный адрес будет http://space-api.test/api/planets.
  3. [PlanetController::class, 'index'] — это "пункт назначения". Мы говорим: "Когда запрос придет, найди класс PlanetController и вызови в нем метод index()".

Теперь всё связано! Запрос -> Маршрут -> Контроллер -> Метод.

А что, если нам нужно получить одну планету по ее ID? Например, /api/planets/5.

// Маршрут для получения конкретной планеты
Route::get('/planets/{planet}', [PlanetController::class, 'show']);

Здесь {planet} — это "шаблон" или переменная. Laravel понимает, что на этом месте может быть что угодно (ID, слаг). Затем он передает это значение в метод show(Planet $planet). Эта "магия", когда Laravel сам находит планету по ID, называется Route Model Binding.


3. Путь мастера: apiResource — одна строка, чтобы править всеми

Создавать каждый маршрут вручную (для index, show, store, update, destroy) утомительно. Разработчики Laravel это понимают, поэтому создали мощный помощник — apiResource.

Удалите все, что мы написали, и замените одной строкой:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PlanetController;

Route::apiResource('planets', PlanetController::class);

Что эта одна строка делает под капотом? Она автоматически создает целый набор маршрутов для стандартных CRUD-операций, которые мы уже реализовали в контроллере.

Метод URL Направляется в метод Назначение
GET /api/planets index() Получить список всех планет
POST /api/planets store() Создать новую планету
GET /api/planets/{planet} show() Показать одну конкретную планету
PUT/PATCH /api/planets/{planet} update() Обновить существующую планету
DELETE /api/planets/{planet} destroy() Удалить планету

Вы можете убедиться в этом сами. Выполните в терминале команду:

php artisan route:list --path=api

Вы увидите таблицу со всеми созданными маршрутами. apiResource — это ваш лучший друг для экономии времени при создании стандартных API.


4. Специальные миссии и порядок маршрутов

Что если нам нужен нестандартный маршрут, которого нет в apiResource? Например, получить случайную планету по адресу /api/planets/random.

Давайте добавим его. Но здесь есть смертельно важная ловушка, в которую попадают 9 из 10 новичков.

Неправильный порядок (НЕ РАБОТАЕТ!):

Route::apiResource('planets', PlanetController::class);
Route::get('/planets/random', [PlanetController::class, 'random']); // <-- НЕ СРАБОТАЕТ
Почему? Laravel читает маршруты сверху вниз. Он увидит Route::apiResource, который создал маршрут GET /planets/{planet}. Когда вы запросите /planets/random, Laravel подумает, что "random" — это ID планеты, и попытается найти в базе данных планету с ID "random" и вы получите ошибку.

Правильный порядок (РАБОТАЕТ!):

<?php
use App\Http\Controllers\PlanetController;
use Illuminate\Support\Facades\Route;

// 1. Сначала объявляем КОНКРЕТНЫЕ маршруты
Route::get('/planets/random', [PlanetController::class, 'random']);

// 2. И только потом объявляем ОБЩИЕ маршруты с переменными
Route::apiResource('planets', PlanetController::class);

⚠️ Важно!

Чтобы проверить маршрут api/planets/random, нужно добавить новый обработчик в PlanetController:

<?php
public function random(Request $request)
{
   $planet = Planet::inRandomOrder()->first();
   return response()->json($planet);
}

Правило: Всегда объявляйте более конкретные маршруты (такие как /random) перед более общими и шаблонными маршрутами (такими как /{planet}).


5. Группировка: Наводим порядок

Когда маршрутов становится много, их можно и нужно группировать.

A. Версионирование API Чтобы в будущем не сломать старые приложения, которые используют ваше API, принято добавлять версию в URL, например /api/v1/....

<?php
Route::prefix('v1')->group(function () {
    // Все маршруты внутри этой группы получат префикс /v1
    // Итоговый URL: /api/v1/planets
    Route::get('/planets/random', [PlanetController::class, 'random']);
    Route::apiResource('planets', PlanetController::class);
});

B. Защита маршрутов (Middleware) Представим, что смотреть планеты могут все, а вот создавать, обновлять и удалять — только авторизованные пользователи.

<?php
// Публичные маршруты, доступные всем
Route::get('/planets', [PlanetController::class, 'index']);
Route::get('/planets/{planet}', [PlanetController::class, 'show']);

// Группа маршрутов, требующая "пропуска" (аутентификации)
Route::middleware('auth:sanctum')->group(function () {
    Route::post('/planets', [PlanetController::class, 'store']);
    Route::put('/planets/{planet}', [PlanetController::class, 'update']);
    Route::delete('/planets/{planet}', [PlanetController::class, 'destroy']);
});

Здесь middleware('auth:sanctum') — это как охранник, который проверяет "пропуск" у каждого, кто пытается получить доступ к маршрутам внутри группы.


6. Тестирование через Postman

Теперь, когда все маршруты проложены, пора их проверить.

  1. Если используете Herd: Ваш сайт уже работает по адресу типа http://space-api.test.
  2. Если нет: Запустите локальный сервер командой php artisan serve. Адрес будет http://localhost:8000.

Откройте Postman и отправьте запросы:

  • GET http://space-api.test/api/planets
  • GET http://space-api.test/api/planets/random
  • POST http://space-api.test/api/planets (не забудьте добавить JSON-тело запроса на вкладке Body -> raw -> JSON).

Пример POST-запроса:

{
    "name": "Kepler-186f",
    "description": "Первая планета земного размера в обитаемой зоне",
    "size_km": 15000,
    "solar_system": "Kepler-186",
    "is_habitable": true
}


8. Частые ошибки маршрутизации

  1. 404 Not Found
    • Неправильный URL (/api/planet вместо /api/planets)
    • Забыли php artisan serve
  2. 405 Method Not Allowed
    • Неверный HTTP-метод (например, GET вместо POST)
  3. Missing Controller
    • Опечатка в имени контроллера (PlanetControler)
  4. Route Name Collision
    • Повторяющиеся имена маршрутов

Квиз для закрепления

1. Файл для API-маршрутов в Laravel:

2. Автоматический префикс для API-роутов:

3. Метод для создания 5 CRUD-маршрутов:

4. Route::prefix('v1') используется для:

5. Просмотр всех маршрутов:


🚀 Итог главы:

Вы построили "гиперпространственные маршруты" для космического API! Теперь:

  • 🗺️ Все эндпоинты доступны по /api/...
  • 🔗 Ресурсные маршруты подключены к контроллеру
  • 🛡️ Добавлены кастомные маршруты для специальных операций
  • ✅ Маршруты протестированы через Postman

Вселенная открыта для запросов! Далее мы добавим защиту от "космического мусора" — валидацию данных.

📌 Проверка:

  1. Выполните php artisan route:list
  2. Убедитесь, что видите 5+ маршрутов для planets
  3. Проверьте работу GET /api/planets в браузере/Postman

⚠️ Если ошибка 404:

  • Проверьте наличие Route::apiResource в routes/api.php
  • Убедитесь, что сервер запущен (php artisan serve)
  • Для Windows: разрешите порт 8000 в брандмауэре