it-swarm.com.ru

Laravel Lumen Ensure JSON ответ

Я новичок в Laravel и Lumen. Я хочу убедиться, что я всегда получаю только объект JSON в качестве вывода. Как я могу сделать это в Lumen?

Я могу получить ответ JSON, используя response()->json($response);. Но когда происходит ошибка, API выдает ошибки text/html. Но я хочу только application/json ответов.

Заранее спасибо.

10
John Fonseka

Вам нужно настроить обработчик исключений (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(),
        ]
    ]);
}
26
Wader

Более точное решение, основанное на ответе @ 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());
}
5
MTVS

Я просто делаю это, если я работаю с API

<?php namespace App\Exceptions;

use Exception;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Illuminate\Http\Response;

class Handler extends ExceptionHandler
{
   /**
    * A list of the exception types that should not be reported.
    *
    * @var array
    */
  protected $dontReport = [
    AuthorizationException::class,
    HttpException::class,
    ModelNotFoundException::class,
    ValidationException::class,
  ];

/**
 * Report or log an exception.
 *
 * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
 *
 * @param Exception $e
 *
 * @throws Exception
 */
public function report(Exception $e): void
{
    parent::report($e);
}

/**
 * @param \Illuminate\Http\Request $request
 * @param Exception $e
 *
 * @return \Illuminate\Http\JsonResponse|Response
 */
public function render($request, Exception $e)
{
    if (env('APP_DEBUG')) {
        return parent::render($request, $e);
    }

    $status = Response::HTTP_INTERNAL_SERVER_ERROR;

    if ($e instanceof HttpResponseException) {
        $status = Response::HTTP_INTERNAL_SERVER_ERROR;
    } elseif ($e instanceof MethodNotAllowedHttpException) {
        $status = Response::HTTP_METHOD_NOT_ALLOWED;
        $e      = new MethodNotAllowedHttpException([], 'HTTP_METHOD_NOT_ALLOWED', $e);
    } elseif ($e instanceof NotFoundHttpException) {
        $status = Response::HTTP_NOT_FOUND;
        $e      = new NotFoundHttpException('HTTP_NOT_FOUND', $e);
    } elseif ($e instanceof AuthorizationException) {
        $status = Response::HTTP_FORBIDDEN;
        $e      = new AuthorizationException('HTTP_FORBIDDEN', $status);
    } elseif ($e instanceof \Dotenv\Exception\ValidationException && $e->getResponse()) {
        $status = Response::HTTP_BAD_REQUEST;
        $e      = new \Dotenv\Exception\ValidationException('HTTP_BAD_REQUEST', $status, $e);
    } elseif ($e) {
        $e = new HttpException($status, 'HTTP_INTERNAL_SERVER_ERROR');
    }

    return response()->json([
        'status'  => $status,
        'message' => $e->getMessage()
    ], $status);

 }
}
0
Mohamed Emad

В качестве MTVS answer вы даже можете использовать класс 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 \Illuminate\Http\JsonResponse)
    {
        return $parentRender;
    }

    return new \Illuminate\Http\JsonResponse([
        'message' => $e instanceof HttpException
            ? $e->getMessage()
            : 'Server Error',
    ], $parentRender->status());
}
0
José Diaz