Laravel Lumen确保JSON响应


Laravel Lumen Ensure JSON response

我是Laravel和Lumen的新手。我想确保我总是只得到一个JSON对象作为输出。我怎么能在鲁门做到这一点?

我可以使用response()->json($response);获得JSON响应。但当发生错误时,API会给我text/html错误。但我只想要application/json的回复。

提前谢谢。

您需要调整异常处理程序(app/Exceptions/Handler.php)以返回所需的响应。

这是可以做什么的一个非常基本的例子。

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());
}

我建议您添加一个中间件,将Accept标头设置为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
]);

对于拉拉威尔来说,这几乎是一个相同的过程。现在,错误处理程序将始终返回json,而不是纯文本/html。

我知道这是一个很老的问题,但我只是偶然发现了它。默认情况下,如果请求者";想要";

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";lumen将自动返回一个JSON响应。例如curl -H "Accept: application/json" https://example.com/my-erroring-endpint

使用它可以避免编写自定义错误处理程序。