Laravel 流明确保 JSON 响应
Laravel Lumen Ensure JSON response
我是 Laravel 和 Lumen 的新手。我想确保我总是只得到一个 JSON 对象作为输出。我如何在 Lumen 中执行此操作?
我可以使用 response()->json($response);
获得 JSON 响应。但是当发生错误时,API 给我 text/html
错误。但我只想要 application/json
个回复。
提前致谢。
您需要将异常处理程序 (app/Exceptions/Handler.php
) 调整为 return 您想要的响应。
这是一个非常基本的例子,可以说明可以做什么。
public function render($request, Exception $e)
{
$rendered = parent::render($request, $e);
return response()->json([
'error' => [
'code' => $rendered->getStatusCode(),
'message' => $e->getMessage(),
]
], $rendered->getStatusCode());
}
基于@Wader 的回答更准确的解决方案可以是:
use Illuminate\Http\JsonResponse;
public function render($request, Exception $e)
{
$parentRender = parent::render($request, $e);
// if parent returns a JsonResponse
// for example in case of a ValidationException
if ($parentRender instanceof JsonResponse)
{
return $parentRender;
}
return new JsonResponse([
'message' => $e instanceof HttpException
? $e->getMessage()
: 'Server Error',
], $parentRender->status());
}
我知道这是一个很老的问题,但我只是偶然发现了它。
默认情况下,如果请求者“想要”它,Lumen 将 return 一个 JSON 响应。
vendor/laravel/lumen-framework/src/Exceptions/Handler.php:110
return $request->expectsJson()
? $this->prepareJsonResponse($request, $e)
: $this->prepareResponse($request, $e);
这归结为
vendor/illuminate/http/Concerns/InteractsWithContentTypes.php:52
$acceptable = $this->getAcceptableContentTypes();
return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);
这意味着如果您为“application/json”指定一个“接受”header,流明将自动return一个JSON响应。
例如 curl -H "Accept: application/json" https://example.com/my-erroring-endpint
使用它可以让您不必编写自定义错误处理程序。
我建议您添加一个中间件,将 Accept
header 设置为 application/json
。
,而不是接触异常处理程序
例如,您可以创建一个名为 RequestsAcceptJson
的中间件并这样定义它:
<?php
namespace App\Http\Middleware;
use Closure;
class RequestsAcceptJson
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$acceptHeader = strtolower($request->headers->get('accept'));
// If the accept header is not set to application/json
// We attach it and continue the request
if ($acceptHeader !== 'application/json') {
$request->headers->set('Accept', 'application/json');
}
return $next($request);
}
}
然后你只需要将它注册为一个全局中间件就可以在你的api的每个请求中运行。在 lumen 中,您可以通过在 bootstrap/app.php
中的中间件调用中添加 class 来做到这一点
$app->middleware([
App\Http\Middleware\RequestsAcceptJson::class
]);
Laravel 过程几乎相同。现在错误处理程序将始终 return a json 而不是普通的 text/html.
我是 Laravel 和 Lumen 的新手。我想确保我总是只得到一个 JSON 对象作为输出。我如何在 Lumen 中执行此操作?
我可以使用 response()->json($response);
获得 JSON 响应。但是当发生错误时,API 给我 text/html
错误。但我只想要 application/json
个回复。
提前致谢。
您需要将异常处理程序 (app/Exceptions/Handler.php
) 调整为 return 您想要的响应。
这是一个非常基本的例子,可以说明可以做什么。
public function render($request, Exception $e)
{
$rendered = parent::render($request, $e);
return response()->json([
'error' => [
'code' => $rendered->getStatusCode(),
'message' => $e->getMessage(),
]
], $rendered->getStatusCode());
}
基于@Wader 的回答更准确的解决方案可以是:
use Illuminate\Http\JsonResponse;
public function render($request, Exception $e)
{
$parentRender = parent::render($request, $e);
// if parent returns a JsonResponse
// for example in case of a ValidationException
if ($parentRender instanceof JsonResponse)
{
return $parentRender;
}
return new JsonResponse([
'message' => $e instanceof HttpException
? $e->getMessage()
: 'Server Error',
], $parentRender->status());
}
我知道这是一个很老的问题,但我只是偶然发现了它。 默认情况下,如果请求者“想要”它,Lumen 将 return 一个 JSON 响应。
vendor/laravel/lumen-framework/src/Exceptions/Handler.php:110
return $request->expectsJson()
? $this->prepareJsonResponse($request, $e)
: $this->prepareResponse($request, $e);
这归结为
vendor/illuminate/http/Concerns/InteractsWithContentTypes.php:52
$acceptable = $this->getAcceptableContentTypes();
return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);
这意味着如果您为“application/json”指定一个“接受”header,流明将自动return一个JSON响应。
例如 curl -H "Accept: application/json" https://example.com/my-erroring-endpint
使用它可以让您不必编写自定义错误处理程序。
我建议您添加一个中间件,将 Accept
header 设置为 application/json
。
例如,您可以创建一个名为 RequestsAcceptJson
的中间件并这样定义它:
<?php
namespace App\Http\Middleware;
use Closure;
class RequestsAcceptJson
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$acceptHeader = strtolower($request->headers->get('accept'));
// If the accept header is not set to application/json
// We attach it and continue the request
if ($acceptHeader !== 'application/json') {
$request->headers->set('Accept', 'application/json');
}
return $next($request);
}
}
然后你只需要将它注册为一个全局中间件就可以在你的api的每个请求中运行。在 lumen 中,您可以通过在 bootstrap/app.php
$app->middleware([
App\Http\Middleware\RequestsAcceptJson::class
]);
Laravel 过程几乎相同。现在错误处理程序将始终 return a json 而不是普通的 text/html.