web-dev-qa-db-fra.com

Laravel Lumen Assurez la réponse JSON

Je suis nouveau à Laravel et à Lumen. Je veux m'assurer de toujours obtenir uniquement un objet JSON en sortie. Comment puis-je faire cela dans Lumen?

Je peux obtenir une réponse JSON en utilisant response()->json($response);. Mais lorsqu'une erreur survient, l'API me donne des erreurs text/html. Mais je ne veux que des réponses application/json.

Merci d'avance.

10
John Fonseka

Vous devrez ajuster votre gestionnaire d'exceptions (app/Exceptions/Handler.php) pour renvoyer la réponse souhaitée.

Ceci est un exemple très basique de ce qui peut être fait.

public function render($request, Exception $e)
{
    $rendered = parent::render($request, $e);

    return response()->json([
        'error' => [
            'code' => $rendered->getStatusCode(),
            'message' => $e->getMessage(),
        ]
    ]);
}
26
Wader

Une solution plus précise basée sur la réponse de @ Wader peut être:

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

Je fais juste cela si je travaille avec des 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

En tant que MTVS answer, vous pouvez même utiliser la classe JsonResponse pour formater votre réponse, et l'utiliser en tant que membre statique dans la méthode de rendu, sans l'importer dans l'espace de noms Handler comme ceci:

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