Laravel 5.7 ModelNotFoundException不为API调用返回json

I want to return a json response when an api call is made to a laravel 5.7 app api route when the model is not found. To do this I have modified the render() method of app\Exceptions\Handler.php like this

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

        return parent::render($request, $exception);
    }

and my controller show() method is using a Book model like this

public function show(Book $book)
    {
        return new BookResource($book->load('ratings'));
    }

Test on postman, a get call to localhost:8000/api/books/1 (id 1 has been deleted) keeps returning the default laravel 404 not found page instead of json.

Have I missed a step or something? I also noticed that adding a conditional statement inside the controller show() method like this

public function show(Book $book)
    {
        if ($book) {
            return new BookResource($book->load('ratings'));
        } else {
            return response()->json(['message' => 'Not found'], 404);
        }
    }

returns the same html result instead of json.

What will be the proper way to handle this scenario?

You can remove $request->wantsJson

or you can set the header in your request "Accept" => "application/json"

May this can help you:

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

        return parent::render($request, $exception);
    }

Your code is correct. The problem is that you are probably testing it on a Local environment so in your .env you have set:

APP_DEBUG=true, switch it to APP_DEBUG=false and you will see your custom message.

PS: $request->wantsJson() is not necessary if your clients send the correct header info, eg: 'accept:application/json'