jsonlaravelutf-8laravel-middleware

Laravel: Encode JSON responses in UTF-8


I want to encode the JSON responses of my API to UTF-8, but every time I make a response I don't want to do this:

return response()->json($res,200,['Content-type'=>'application/json;charset=utf-8'],JSON_UNESCAPED_UNICODE);

So I thought about making a middleware for all API routes which handle(...) function would be this:

public function handle($request, Closure $next) {
    $response = $next($request);
    $response->header('Content-type','application/json; charset=utf-8');
    return $next($request);
}

The problem is that it doesn't work, the Content-type header of my responses is still application/json and not application/json; charset=utf-8; maybe because the json(...) function already sets a Content-type header and I cannot override it.

How should I do?

Thank you for your help.


Solution

  • Its right there in the documentation, you want to use after middleware (following code is from top of my head and it should work):

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class AfterMiddleware
    {
        public function handle($request, Closure $next)
        {
    
            /** @var array $data */ // you need to return array from controller
            $data = $next($request);
    
            return response()->json($data, 200, ['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'],
            JSON_UNESCAPED_UNICODE);
        }
    }
    

    With above approach we can spot two anti-patterns:

    Removing middleware and using controller only

    Put following code in app/Http/Controller.php

    protected function jsonResponse($data, $code = 200)
    {
        return response()->json($data, $code,
            ['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'], JSON_UNESCAPED_UNICODE);
    }
    

    in any of the controllers that are extended by base controller (app/Http/Controller.php) you can use $this->jsonResponse($data);

    How pros do it

    They use eloquent resources or if there is more going on fractal is the way to go (in Laravel use spatie wrapper - https://github.com/spatie/laravel-fractal).