如何在Laravel中的每个响应上强制使用JSON响应?

2022-08-30 19:26:42

我正在尝试使用Laravel框架构建一个REST API,我想要一种方法来强制API始终使用JSON进行响应,而不是通过这样做:

return Response::json($data);

换句话说,我希望每个响应都是JSON。有没有一个好方法可以做到这一点?

更新:即使在未找到异常等异常时,响应也必须为 JSON。


答案 1

按照 Alexander Lichter 的建议创建一个中间件,为每个请求设置标头:Accept

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ForceJsonResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $request->headers->set('Accept', 'application/json');

        return $next($request);
    }
}

将其添加到文件中:$routeMiddlewareapp/Http/Kernel.php

protected $routeMiddleware = [
    (...)
    'json.response' => \App\Http\Middleware\ForceJsonResponse::class,
];

现在,您可以包装应返回 JSON 的所有路由:

Route::group(['middleware' => ['json.response']], function () { ... });

编辑: 对于拉拉维尔 6.9+

赋予中间件优先于其他中间件 - 在设置标头之前,处理请求被其他中间件(如中间件)终止的情况。json.responseAuthorizeAccept

为此 , 使用以下命令重写类 () 的构造函数:App\Http\Kernelapp/Http/Kernel.php

    public function __construct( Application $app, Router $router ) {
        parent::__construct( $app, $router );
        $this->prependToMiddlewarePriority(\App\Http\Middleware\ForceJsonResponse::class);
    }

答案 2

我知道这个问题已经得到了回答,但这些都不是很好的解决方案,因为它们以不可预测的方式改变了状态代码。最好的解决方案是添加适当的标头,以便Laravel返回JSON(我认为它),或者按照这个很棒的教程总是告诉Laravel返回JSON:https://hackernoon.com/always-return-json-with-laravel-api-870c46c5efb2Accept: application/json

如果您想更具选择性或适应更复杂的解决方案,也可以通过中间件执行此操作。


推荐