How to set header for all requests in route group

12,937

Solution 1

You can create a middleware for that.

You'll have check and enforce the Accept header so Laravel will output json no matter what..

class WeWantJson
{
    /**
     * We only accept json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $acceptHeader = $request->header('Accept');
        if ($acceptHeader != 'application/json') {
            return response()->json([], 400);
        }

        return $next($request);
    }
}

And in your App\Http\Kernel you can add the middleware to you api group. Then there's no need to manually add it in the routes/routegroups.


Edit:

You could also add a middleware to enforce json no matter what...

class EnforceJson
{
    /**
     * Enforce json
     *
     * @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);
    }
}

Solution 2

You can use simple middleware like this

class OnlyAcceptJsonMiddleware
{
    /**
     * We only accept json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
       // Verify if request is JSON
        if (!$request->expectsJson()) {
            return response(['message' => 'Only JSON requests are allowed'], 406);
        }

        return $next($request);
    }
}

And in your App\Http\Kernel you can add the middleware to you api group or any group that you wanna use.

Share:
12,937

Related videos on Youtube

Gloire
Author by

Gloire

Programming Enthusiast, Lover of life and pretty positive guy :D

Updated on August 28, 2022

Comments

  • Gloire
    Gloire over 1 year

    I'm creating an API with Laravel 5.4 and it all works well. I've used the following middleware => auth:api like this

    Route::group(['middleware' => 'auth:api'], function(){ 
        Route::get('URIValue', ControllerName@action) //Example
    });
    

    I've tested it with postman and it works well when the request header contains the following keys and values :

    • Authorization:Bearer api_token
    • Accept:application/json

    When the api_token is invalid the unauthenticated function of the Handler class is executed. The default response that laravel returns is

    'error' => 'Unauthenticated' // in JSON format
    

    But when the Accept header is not set, laravel returns a view by default. But with an API, views are not acceptable.

    How can I force laravel to check that the Accept header is set with the right value (in this case the value must be => accept/json) for every single request for the routes that are in the route group?

    Something like:

    protected function mapApiRoutes()
    {
        Route::prefix('api')
              ->middleware('api')
              ->namespace($this->namespace)
              ->header('Accept' => 'application/json') //this
              ->group(base_path('routes/api.php'));
    }
    

    or

    Route::group(['middleware'  => 'auth:api', 
                  'headers'     => ['Accept' => 'application/json']
                 ], function(){ 
                        Route::get('URIValue', ControllerName@action) //Example
                 });
    
  • Gloire
    Gloire almost 7 years
    I did think of creating a middleware but I'm looking for a Laravel out of the box solution. Should there not be one I guess I will just have to create a middleware that is similar to yours.
  • Robert
    Robert almost 7 years
    Middleware is the laravel out of the box solution. I've added another example in which you simply overwrite the accept header before handling the request.
  • Gloire
    Gloire almost 7 years
    Hahaha well that is true. I like the second example. Since it's an API might as well just set the header at every single request to avoid errors.
  • Robert
    Robert almost 7 years
    Well... it is less strict, and for some reason you might want to accept other types later on. Though that's rarely the case nowadays :) I would prefer keeping it strict and output the error when the client does not set the Accept header properly, but that's my opinion.
  • Abderrahmane TAHRI JOUTI
    Abderrahmane TAHRI JOUTI about 6 years
    @Robert in Laravel 5.6 : $request->header('Accept', 'application/json'); retrieves the value and does not alter the request. So this is not going to work. This one works stackoverflow.com/a/35319899/614277