Laravel API 404 ответ: Возвращаем JSON вместо страницы с ошибкой

Laravel API 404 ответ

Если вы создаете проект на Laravel как с веб-страницами, так и с API, то вам необходимо для каждого из них настраивать вывод ошибок. При веб-просмотре должны быть страницы с ошибками, а API должен возвращать JSON с кодами состояния. Как это сделать? Я покажу пример с 404-ой ошибкой Not Found.

Представьте себе такой сценарий — веб-страница профиля пользователя и аналогичный запрос к API.

Итак, у нас есть app/Http/Controllers/UserController.php:

public function show(User $user)
{
    return view('users.show', compact('user'));
}

И у нас есть API — app/Http/Controllers/API/V1/UserController.php:

public function show(User $user)
{
    return $user;
}

Второй пример просто вернет JSON-коллекцию без какого-либо шаблона. И это нормально.

Проблемы начинаются, когда вы пытаетесь вызвать этот API, а пользователя нет. Так как мы здесь используем привязку модели к маршруту и передаем (User $user) напрямую, то под капотом он запускает метод User::findOrFail($id), выдает исключение ModelNotFoundException и показывает страницу 404.

На стороне API вы также получаете страницу с ошибкой вместо ошибки JSON:

Итак, наша цель состоит в том, чтобы, ничего не меняя для веб-версии, переопределить обработку ошибок API и получить правильный JSON.

Для этого нам нужно добавить следующую логику в класс app/Exceptions/Handler.php:

use Illuminate\Database\Eloquent\ModelNotFoundException;

// ...

public function render($request, Exception $exception)
{
    if ($exception instanceof ModelNotFoundException && $request->wantsJson()) {
        return response()->json(['message' => 'Not Found!'], 404);
    }

И всё! Вы получите правильно сформированный ответ:

И это не меняет дефолтное поведение для веб-запросов, оно все также отобразит старую добрую 404-ую страницу.

 

Автор: Povilas Korop
Перевод: Demiurge Ash