Ad

Return Every Request As Plain Json Laravel Using Middleware

- 1 answer

I have a route in my web.php that returns a view:

Route::get('/', function () {
    return view('welcome');
});

welcome is default Laravel view welcome.blade.php.

I have Middleware called AlwaysReturnJson and it contains:

<?php

namespace App\Http\Middleware;

use Closure;

class AlwaysReturnJson
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        $request->headers->set('Accept', 'application/json');
        return $next($request);
    }
}

I set up this middleware in Kernel.php as global middleware:

 protected $middleware = [
        \App\Http\Middleware\AlwaysReturnJson::class
    ];

What I expect is to get plain text/json of welcome file in my browser when I navigate to given route but I always get it as html and it render page properly. I checked it, it applies middleware on every request so that is not a problem. Why is this happening and shouldn't it convert that view to a plain text? Am I doing something wrong?

Ad

Answer

If you want to set a header for your response you can do this:

namespace App\Http\Middleware;

use Closure;

class AlwaysReturnJson
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('Content-Type', 'application/json');

        return $response;
    }
}

If you want to force return valid json content use this middleware instead:

namespace App\Http\Middleware;

use Closure;

class AlwaysReturnJson
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        return response()->json($response->getContent());
    }
}

See Laravel docs about after middleware for more info.

You can alternatively return json response on your controller without any middleware needed:

Route::get('/', function () {
    return response()->json(
        view('welcome')->render()
    );
});
Ad
source: stackoverflow.com
Ad