Laravel Lumen Ensure JSON response Laravel Lumen Ensure JSON response laravel laravel

Laravel Lumen Ensure JSON response


You'll need to adjust your exception handler (app/Exceptions/Handler.php) to return the response you want.

This is a very basic example of what can be done.

public function render($request, Exception $e){    $rendered = parent::render($request, $e);    return response()->json([        'error' => [            'code' => $rendered->getStatusCode(),            'message' => $e->getMessage(),        ]    ], $rendered->getStatusCode());}


A more accurate solution based on @Wader's answer can be:

use Illuminate\Http\JsonResponse;public function render($request, Exception $e){    $parentRender = parent::render($request, $e);    // if parent returns a JsonResponse     // for example in case of a ValidationException     if ($parentRender instanceof JsonResponse)    {        return $parentRender;    }    return new JsonResponse([        'message' => $e instanceof HttpException            ? $e->getMessage()            : 'Server Error',    ], $parentRender->status());}


Instead of touching the exception handler, I suggest you to add a middleware that sets the Accept header to application/json.

For example, you can create a middleware called RequestsAcceptJson and define it this way:

<?phpnamespace App\Http\Middleware;use Closure;class RequestsAcceptJson{    /**     * Handle an incoming request.     *     * @param  \Illuminate\Http\Request  $request     * @param  \Closure  $next     * @return mixed     */    public function handle($request, Closure $next)    {        $acceptHeader = strtolower($request->headers->get('accept'));        // If the accept header is not set to application/json        // We attach it and continue the request        if ($acceptHeader !== 'application/json') {            $request->headers->set('Accept', 'application/json');        }        return $next($request);    }}

Then you only need to register it as a global middleware to be run in every request to your api. In lumen you can do that by adding the class in the middleware call inside your bootstrap/app.php

$app->middleware([    App\Http\Middleware\RequestsAcceptJson::class]);

With Laravel it's pretty much the same process. Now the error handler will always return a json instead of plain text/html.