Строим REST API на Laravel

Рейтинг: 67.6% · 8 голосов
Курс по Laravel: маршруты, Eloquent, Blade, миграции, очереди и API. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
oleg_php
Сообщения: 25
Зарегистрирован: 14 май 2026, 08:06

Строим REST API на Laravel

Сообщение oleg_php »

АкадемияLaravel с нуляГлава 12 из 18
Оглавление курса (18)
  1. Знакомство с Laravel и установка окружения
  2. Маршруты и контроллеры
  3. Blade: шаблоны и вёрстка страниц
  4. Миграции и структура базы данных
  5. Eloquent ORM: модели и CRUD
  6. Связи в Eloquent: hasMany, belongsTo и другие
  7. Формы и валидация данных
  8. Аутентификация пользователей
  9. Middleware и защита маршрутов
  10. Очереди и фоновые задачи
  11. Отправка почты и уведомления
  12. Строим REST API на Laravel (вы здесь)
  13. Авторизация: Gates и Policies
  14. Работа с файлами: загрузка, Storage, диски local и S3
  15. Тестирование: Pest и PHPUnit, фабрики, сидеры, RefreshDatabase
  16. Сервис-контейнер, провайдеры, свои artisan-команды и планировщик
  17. Деплой в продакшен и обзор современного фронтенда (Vite, Livewire, Inertia)
  18. События и слушатели, кеширование, логирование
За одиннадцать глав мы собрали классическое веб-приложение: маршруты, Eloquent, формы, аутентификация. Но мобильному приложению или фронтенду на Vue ваш HTML не нужен, им нужен JSON. В этой главе построим полноценный REST API для статей блога: с токенами, валидацией и честными кодами ответов.

Подготовка:

Начиная с Laravel 11 файла routes/api.php в свежем проекте нет, его подключают отдельной командой. Она же ставит Sanctum, пакет для токенной аутентификации, и регистрирует всё в bootstrap/app.php. Контроллер генерируем с флагом --api: получим те же методы, что у resource-контроллера из главы 2, но без create и edit, ведь формы теперь рисует клиент, а не сервер.

Код: Выделить всё

php artisan install:api
php artisan make:controller Api/ArticleController --api --model=Article
php artisan make:resource ArticleResource
Все маршруты из routes/api.php автоматически получают префикс /api и middleware-группу api, без сессий и CSRF. Версионирование закладывайте в первый день: когда у API появятся живые клиенты, менять формат ответов без /v2 уже не выйдет. Чтение сделаем публичным, а запись закроем токеном, как учила глава 9.

Код: Выделить всё

use App\Http\Controllers\Api\ArticleController;

Route::prefix('v1')->group(function () {
    Route::apiResource('articles', ArticleController::class)
        ->only(['index', 'show']);

    Route::middleware('auth:sanctum')->group(function () {
        Route::apiResource('articles', ArticleController::class)
            ->except(['index', 'show']);
    });
});
Ресурсы вместо голых моделей:

Можно вернуть из контроллера return Article::all(), и Laravel честно отдаст JSON. Не делайте так. Формат ответа намертво привяжется к структуре таблицы, и первое же переименование колонки сломает мобильное приложение. Нужна прослойка, она называется API Resource.

Код: Выделить всё

// app/Http/Resources/ArticleResource.php
public function toArray(Request $request): array
{
    return [
        'id' => $this->id,
        'title' => $this->title,
        'body' => $this->body,
        'author' => $this->whenLoaded('user', fn () => $this->user->name),
        'created_at' => $this->created_at->toIso8601String(),
    ];
}

// app/Http/Controllers/Api/ArticleController.php
public function index()
{
    return ArticleResource::collection(
        Article::with('user')->latest()->paginate(20)
    );
}

public function store(StoreArticleRequest $request)
{
    $article = $request->user()->articles()->create($request->validated());

    return ArticleResource::make($article)
        ->response()
        ->setStatusCode(201);
}
Заметьте: collection() поверх paginate() сам добавит в ответ блоки links и meta с номерами страниц. А StoreArticleRequest это тот же form request из главы 7, при ошибке валидации API-клиент получит 422 с JSON-описанием полей, дописывать ничего не нужно. Коды соблюдайте честно: 201 при создании, 204 без тела при удалении (return response()->noContent()), 404 отдаст сам route model binding.

Токены через Sanctum:

Сессии для API не подходят. Клиент один раз обменивает email и пароль на токен, а дальше шлет его в каждом запросе в заголовке Authorization: Bearer.

Код: Выделить всё

Route::post('/v1/login', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    $user = User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        return response()->json(['message' => 'Неверный email или пароль'], 401);
    }

    return ['token' => $user->createToken('mobile')->plainTextToken];
});
Проверять удобно через Postman или curl: шлете POST на /api/v1/login, забираете токен из ответа и подставляете его в Authorization при создании статьи.

Типичные грабли:

Первые и самые частые: забытый заголовок Accept: application/json. Без него Laravel считает клиента браузером. При ошибке валидации он делает редирект назад вместо 422, а на запрос без токена пытается отправить на страницу логина и падает с ошибкой Route [login] not defined. Приучите клиента слать этот заголовок всегда, а на сервере подстрахуйтесь в bootstrap/app.php через shouldRenderJsonWhen для путей api/*.

Вторые: N+1 из главы 6. Сам по себе whenLoaded связь не грузит, with('user') в контроллере обязателен, иначе список из 20 статей породит 21 запрос к базе.

Третьи: отдача всей таблицы разом. Только paginate(), никаких all() в index. Первый же клиент с парой сотен тысяч записей упрется в лимит памяти PHP, и хорошо если на тестовом сервере, а не в проде.

Что усвоили:

API в Laravel это те же кирпичи, что и раньше: маршруты, контроллеры, Eloquent, form request-ы, middleware. Новое здесь только ресурсы как контракт формата и Sanctum вместо сессий. На этом курс закончен, но не проект: добавьте rate limiting через throttle, напишите тесты на эндпоинты, вынесите тяжелые операции в очереди из главы 10. Фундамент у вас уже есть.
👍3 ❤️3 🔥1 😄 🤔1
✔ Лучший ответ сформирован автоматически — nanasuke
oleg_php писал(а):При ошибке валидации он делает редирект назад вместо 422, а на запрос без токена пытается отправить на страницу логина вот оно что. вчера полчаса тупил, почему postman возвращает 200 и гору html вместо ошибки. добавил Accept: application/json и все встало на место. спасибо!
Перейти к ответу →
Аватара пользователя
docholiday
Сообщения: 1
Зарегистрирован: 28 май 2026, 05:07

Re: Строим REST API на Laravel

Сообщение docholiday »

от себя добавлю: после регистрации маршрутов полезно глянуть php artisan route:list --path=api. сразу видно все эндпоинты, методы и какие из них под auth:sanctum. на большом api очень спасает, особенно когда only/except начинают путаться
👍 ❤️ 🔥1 😄 🤔
Аватара пользователя
nanasuke
Сообщения: 2
Зарегистрирован: 28 май 2026, 17:28

Re: Строим REST API на Laravel

Сообщение nanasuke »

✔ Лучший ответ — сформирован автоматически
oleg_php писал(а):При ошибке валидации он делает редирект назад вместо 422, а на запрос без токена пытается отправить на страницу логина
вот оно что. вчера полчаса тупил, почему postman возвращает 200 и гору html вместо ошибки. добавил Accept: application/json и все встало на место. спасибо!
👍1 ❤️ 🔥1 😄 🤔1
Аватара пользователя
python_sre
Сообщения: 1
Зарегистрирован: 11 май 2026, 20:24

Re: Строим REST API на Laravel

Сообщение python_sre »

вопрос про createToken('mobile'). 'mobile' это просто имя для себя или оно на что-то влияет? и как потом разлогинить юзера, токены же в personal_access_tokens лежат, их руками удалять через tokens()->delete()?
👍1 ❤️1 🔥1 😄 🤔
Аватара пользователя
cppops
Сообщения: 4
Зарегистрирован: 13 май 2026, 02:18

Re: Строим REST API на Laravel

Сообщение cppops »

а если фронт это SPA на том же домене, vue + vite прямо в этом же проекте? видел в доках sanctum какой-то spa режим с куками вместо токенов. для него тоже install:api хватит или там отдельная настройка с EnsureFrontendRequestsAreStateful?
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Отправка почты и уведомления
Следующая глава →
Авторизация: Gates и Policies

Все главы курса «Laravel с нуля»

Поделиться темой: ✈ Telegram VK

Вернуться в «Laravel с нуля»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей