你如何在 Laravel 中的每个响应上强制一个 JSON 响应?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36366727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 13:31:06  来源:igfitidea点击:

How do you force a JSON response on every response in Laravel?

phpjsonrestlaravel

提问by Mustafa Dwekat

I'm trying to build a REST api using Laravel Framework, I want a way to force the API to always responed with JSON not by doing this manulaly like:

我正在尝试使用 Laravel 框架构建 REST api,我想要一种方法来强制 API 始终响应 JSON,而不是通过手动执行以下操作:

return Response::json($data);

In other words I want every response to be JSON. Is there a good way to do that?

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

Update:The response must be JSON even on exceptions like not found exception.

更新:即使出现未找到异常等异常,响应也必须是 JSON。

采纳答案by DuckPuncher

To return JSONin the controller just return $data;

返回JSON控制器只是return $data;

For a JSONresponse on errors, go to app\Exceptions\Handler.phpfile and look at the rendermethod.

有关JSON错误的响应,请转到app\Exceptions\Handler.php文件并查看render方法。

You should be able to re-write it to look something like this:

您应该能够重新编写它,使其看起来像这样:

public function render($request, Exception $e)
{
    // turn $e into an array.
    // this is sending status code of 500
    // get headers from $request.
    return response()->json($e, 500);
}

However you will have to decide what to do with $e, because it needs to be an array. You can also set the status code and header array.

但是,您必须决定如何处理$e,因为它必须是array. 您还可以设置状态代码和标题数组。

But then on any error, it will return a JSONresponse.

但是如果出现任何错误,它将返回一个JSON响应。

Edit: It's also good to note that you can change the reportmethod to handle how laravel logs the error as well. More info here.

编辑:还需要注意的是,您还可以更改report方法来处理 laravel 记录错误的方式。更多信息在这里

回答by M165437

Create a middleware as suggested by Alexander Lichterthat sets the Acceptheader on every request:

按照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);
    }
}

Add it to $routeMiddlewarein the app/Http/Kernel.phpfile:

将它添加到$routeMiddleware了在app/Http/Kernel.php文件中:

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

You can now wrap all routes that should return JSON:

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

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

回答by JonTroncoso

I know this has been answered but these are not good solutions because they change the status code in unpredictable ways. the best solution is to either add the appropriate headers so that Laravel returns JSON (I think its Accept: application/json), or follow this great tutorial to just always tell Laravel to return JSON: https://hackernoon.com/always-return-json-with-laravel-api-870c46c5efb2

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

You could probably also do this through middleware as well if you wanted to be more selective or accommodate a more complex solution.

如果您想要更有选择性或适应更复杂的解决方案,您也可以通过中间件来做到这一点。

回答by Amin Shojaei

You can create an After Middlewareand change structure of all responses

您可以创建After Middleware并更改所有响应的结构

Middleware:

中间件:

namespace App\Http\Middleware;

use Closure;

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

        $newContent = [
            'data' => $response->getOriginalContent(),
            'context' => [
                'code' => $response->getStatusCode()
            ]
        ];

        return $response->setContent($newContent);
    }
}

this middleware will force the response content to be like

这个中间件将强制响应内容像

{
   "data": "response content of controller",
   "context": {
       "code": 200 // status code
   }
}