Как я проектирую API на Laravel под фронт на Vue/React
Когда Laravel стоит за SPA на Vue/React, всё упирается в то, насколько удобно жить фронту. Если API сделан «на автомате», проект быстро превращается в хаос: разные форматы ответов, странные коды ошибок, пляски с авторизацией.
Расскажу, какие правила я закладываю в API сразу, чтобы фронт не страдал.
1. Единый формат ответов
Я договариваюсь так:
- успешный ответ с данными:
{ "data": {...}, "meta": {...} }
- ошибка валидации: 422 и объект errors по полям
- другие ошибки: код по делу (401/403/404/500) и message для фронта
В Laravel это удобно делать через JsonResource и кастомный обработчик исключений, чтобы не плодить return response()->json(...) в каждом контроллере.
2. FormRequest везде, где есть входные данные
Никаких request()->validate() в контроллере, только отдельные классы:
class StorePostRequest extends FormRequest { public function rules(): array { return [ 'title' => ['required','string','max:255'], 'body' => ['required','string'], ]; } }
Плюсы:
- фронт всегда получает одинаковый формат 422 с ошибками по полям
- можно переиспользовать правила между эндпоинтами
- в контроллере остаётся минимум кода
3. Resources вместо «голых» моделей
Я никогда не отдаю модели как есть:
return new PostResource($post);
class PostResource extends JsonResource { public function toArray($request): array { return [ 'id' => $this->id, 'title' => $this->title, 'body' => $this->body, 'author' => [ 'id' => $this->author->id, 'name' => $this->author->name, ], 'created' => $this->created_at->toIso8601String(), ]; } }
Так я могу:
- переименовывать поля без ломки базы
- добавлять вычисляемые свойства
- не светить лишнее (служебные поля, флаги и т.п.)
4. Чёткие URL и действия
Стараюсь держаться REST, без экзотики:
- список: GET /api/v1/posts
- элемент: GET /api/v1/posts/{id}
- создание: POST /api/v1/posts
- обновление: PUT/PATCH /api/v1/posts/{id}
- удаление: DELETE /api/v1/posts/{id}
В Laravel это шикарно ложится на Route::apiResource(). Если нужна нестандартная операция (например, публикация), делаю что-то вроде:
POST /api/v1/posts/{id}/publish
а не загадочный POST /api/v1/publishPost.
5. Авторизация для SPA
Чаще всего использую Sanctum:
- фронт логинится → получает cookie-токен
- дальше просто шлёт запросы с withCredentials
- на бэке всё через auth:sanctum
Главное — договориться, какие маршруты публичные, а какие требуют авторизации, и не тащить логику прав на фронт. Фронт только реагирует на 401/403.
6. Мета и пагинация
Для списков я всегда возвращаю:
{ "data": [ ... ], "meta": { "current_page": 1, "per_page": 20, "total": 135 } }
В Laravel это делается через пагинатор и Resource::collection($paginator). Фронту не нужно изобретать свои счётчики страниц и гадать, есть ли ещё данные.
7. Чек-лист перед тем, как отдавать API фронту
- Все маршруты живут под /api/v1, нет «случайных» урлов
- Все входные данные валидируются через FormRequest
- Ответы завернуты в Resources, модели наружу не торчат
- Формат ошибок единый, есть 422 с ошибками по полям
- Продумана аутентификация (обычно Sanctum) и роли
- Пагинация возвращает meta, фронт не гадает про страницы
Итог
Хороший API для Vue/React на Laravel — это не «магический» код, а набор скучных, но понятных правил: единый формат ответов, FormRequest, Resources, аккуратные URL и нормальная авторизация. Когда это заложено, фронту становится всё равно, на чём бэк, а вам проще менять внутренности, не ломая клиент.
· 30.11
Однажды был у меня опыт столкнуться с проектом с бэком на Java через tomcat. Не понял я его прелести, к тому же в том же проекте Java была лишь переходником к php классам генерации документов
ответить
коммент удалён