Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

luddinus's avatar

Set header in request (middleware)

Hi,

I want to make an api, and by default I want to add the header "Accept: application/json" in a middleware group, this is what I'm trying but it doesn't seems to work.

public function handle($request, $next)
{
   header('Accept: application/json');

   return $next($request);
}

What can I do? Thx.

0 likes
15 replies
igorblumberg's avatar

I'm not sure that this is a good practice but if you must do it, you should add the header to the request:

public function handle($request, $next)
{
    $request->header->add($parameter);

The $parameter must be an array, so take a look on how the $request->header is being sent and then create the $parameter variable.

(I've only used this to add an input to the request, like this $request->request->add(["field"=>$value]))

spekkionu's avatar

In Laravel headers should be set on the response object.

go24's avatar

They didn't quite understand your use case, I did. I was debugging why the validation didn't work. The validation error just response as html or just redirected to the pre-defined redirect. I have to force all internal api client to always Accept Json, as you did in your middleware.

spekkionu's avatar

To set a header in a middleware:

public function handle($request, Closure $next)
    {
        $response = $next($request);

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

        return $response;
    }

For your particular example rather than setting the content type globally it would be better to use the response()->json() helper in your controllers.

JSON Responses

The json method will automatically set the Content-Type header to application/json, as well as convert the given array into JSON using the json_encode PHP function:

return response()->json(['name' => 'Abigail', 'state' => 'CA']);
7 likes
igorblumberg's avatar

If I understood correctly, you want to add the middleware to the request and not to the response. I think the best practise is to ask the consumer of the API to add this header, not adding for them. But if your API will only return JSON you may add for them automatically.

regards,

jaffarhussain1011's avatar

I know its two late but may be this can benefit someone.

You can set header in handle function as below:

public function handle($request, Closure $next){ $request->server->set('HTTP_ACCEPT', 'application/json'); $request->headers = new HeaderBag($request->server->getHeaders()); return $next($request); }

4 likes
martinbean's avatar

You shouldn’t be overriding request headers, otherwise they don’t accurately reflect a request coming into your application. If you have an API and only want to return JSON, then just return JSON:

class SomeController extends Controller
{
    public function someAction()
    {
        $result = SomeModel::someMethod();

        return response()->json($result);
    }
}
Lednerb's avatar

TL;DR

  • You have to use the prefix HTTP_ if you want to set or rewrite a header that should be available in the controller via $request->header('NAME_WITHOUT_PREFIX');
  • You have to set the header on the $request->server not on $request->headers

Maybe it was not your exact use case, but after all of the years I've found this thread, so I will post my solution for others, maybe it helps...

I was working on an API that introduced a new version v2 while the v1 should still work. I've refactored the controllers a lot and renamed a header that was needed in the application.

After hours of searching and experimenting, I've finally got the clue via this comment on Reddit.

    public function handle($request, Closure $next)
    {
        if ($request->header('userToken', false)) {
            // Need to add HTTP_ in order to make this work
            // See: https://www.reddit.com/r/laravel/comments/292ymn/apicentric_laravel_how_to_add_headers_to_internal/ciiq5vn/
            $request->server->set('HTTP_NewTokenName', $request->header('userToken'));

            // $request->headers->set('NewTokenName', $request->header('userToken')); // does not work!
        }

        return $next($request);
    }
  • You have to use the prefix HTTP_ if you want to set or rewrite a header that should be available in the controller via $request->header('NAME_WITHOUT_PREFIX');
  • You have to set the header on the $request->server not on $request->headers

Strange behavior, maybe someone knows a better way to archive this.

abbood's avatar

This simply doesn't work, the request class doesn't have this property (header) anywhere. https://laravel.com/api/5.5/Illuminate/Http/Request.html

$request->header() returns an array like so

- Eval of: '$request->header()'

 ▾ $request->header() = (array [15])
  \
   ▸ $request->header()['authorization'] = (array [1])
   |
   ▸ $request->header()['content-type'] = (array [1])
   |
   ▸ $request->header()['accept'] = (array [1])
   |
   ▸ $request->header()['content-language'] = (array [1])
   |
   ▸ $request->header()['lat'] = (array [1])
   |
   ▸ $request->header()['lon'] = (array [1])
   |
   ▸ $request->header()['location'] = (array [1])
   |
   ▸ $request->header()['platform'] = (array [1])
   |
   ▸ $request->header()['version'] = (array [1])
   |
   ▸ $request->header()['client-device-token'] = (array [1])
   |
   ▸ $request->header()['content-length'] = (array [1])
   |
   ▸ $request->header()['host'] = (array [1])
   |
   ▸ $request->header()['connection'] = (array [1])
   |
   ▸ $request->header()['accept-encoding'] = (array [1])
   |
   ▸ $request->header()['user-agent'] = (array [1])
  /

UselesssCat's avatar

Whether it is a good practice or not depends on the case.

In my case it is necessary that all requests made to the service have a request id. If the id does not exist then I have to create a new one. All this is to follow the requests through the logs (of various micro-services) when an exception is thrown.

This is the way I updated the Headers (in Lumen, but i think es the same for laravel):

use Closure;
use Illuminate\Http\Request;
use Webpatser\Uuid\Uuid;

class CreateRequestIdMiddleware
{
    public const HEADER_NAME = 'request-id';

    public function handle(Request $request, Closure $next)
    {
        $requestId = $request->header(self::HEADER_NAME);

        if ($requestId === null) {
            $uuid = Uuid::generate(4)->string;

            $request->headers->set(self::HEADER_NAME, $uuid);
        }

        return $next($request);
    }
}

So i can access it i my controller

namespace App\Http\Controllers;

use App\Offer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

class OfferController extends Controller
{
    public function all(Request $request): JsonResponse
    {
        dd($request->header('request-id'));

        /* some code */
    }
}

The class Illuminate\Http\Request extends from Symfony\Component\HttpFoundation\Request that has the public attribute $headersof type Symfony\Component\HttpFoundation\HeaderBag.

HeaderBag have the method set defined as

public function set($key, $values, $replace = true) { /* ... */ }
faraweilyas's avatar

Hi,

My use case was to automatically set the header for all api requests so it's easier for mobile devs consuming the api to catch errors in json format at all times without having to worry about adding the header to the request everytime.

This was posted considering laravel 9

Step 1:

Run this in bash to generate the middleware

php artisan make:middleware ApiRequestShouldAcceptJson

Step 2:

This should be in your ApiRequestShouldAcceptJson file

	public function handle(Request $request, Closure $next)
    {
        $request->headers->set('Accept', 'application/json');

        return $next($request);
    }

Step 3:

Add this to your route App\Http\Kernel file in your $routeMiddleware variable

'api.acceptjson' => \App\Http\Middleware\ApiRequestShouldAcceptJson::class,

Step 4:

Add this to your route in the API file in your routes folder

Route::get('/sandbox', function()
{
    // perform your operation here
})
->middleware(['api.acceptjson']);

or add it to a group

Route::middleware(['api.acceptjson'])
->group(function()
    {
        // define routes here
    });

Please or to participate in this conversation.