Juan Fonseka
Soy nuevo en Laravel y en Lumen. Quiero asegurarme de que siempre obtengo solo un objeto JSON como salida. ¿Cómo puedo hacer esto en Lumen?
Puedo obtener una respuesta JSON usando response()->json($response);
. Pero cuando ocurre un error, la API me da text/html
errores pero solo quiero application/json
respuestas
Gracias por adelantado.
Ave zancuda
Deberá ajustar su controlador de excepciones (app/Exceptions/Handler.php
) para devolver la respuesta que desea.
Este es un ejemplo muy básico de lo que se puede hacer.
public function render($request, Exception $e)
{
$rendered = parent::render($request, $e);
return response()->json([
'error' => [
'code' => $rendered->getStatusCode(),
'message' => $e->getMessage(),
]
], $rendered->getStatusCode());
}
-
Gracias por la respuesta. Sin embargo, tengo una pequeña pregunta, ¿puedo hacer esto?
return response()->json(['code' => $rendered->getStatusCode(), 'message' => $e->getMessage()], $rendered->getStatusCode());
Busqué la lista de excepciones y no pude encontrar una lista todavía.– Juan Fonseka
18 mayo 2016 a las 10:50
-
Eso me parece bien. Aquí está la firma del
response()->json()
función. github.com/laravel/lumen-framework/blob/5.2/src/Http/…– Vadeador
18 mayo 2016 a las 11:02
-
Tenga en cuenta que este ejemplo siempre devolverá un
200
Código HTTP. Probablemente no quieras eso. si usafindOrFail()
por ejemplo, elcode
elemento mostrará correctamente un404
pero el resultado general seguirá siendo un200
, que evidentemente no lo es. Para arreglar esto, pasa$rendered->getStatusCode()
dentrojson()
como su segundo parámetro.– Jasón
29 de abril de 2019 a las 10:52
Una solución más precisa basada en la respuesta de @Wader puede ser:
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());
}
-
Buena respuesta completa que incluye la clase necesaria también. voto positivo de mi parte
– Derek Pollard
29 de marzo de 2018 a las 6:01
-
¿Alguna sugerencia para Lumen 8? Gracias
– Kamlesh
29 de julio de 2021 a las 12:47
César Escudero
En lugar de tocar el controlador de excepciones, le sugiero que agregue un middleware que establezca el Accept
encabezado a application/json
.
Por ejemplo, puede crear un middleware llamado RequestsAcceptJson
y definirlo de esta manera:
<?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);
}
}
Luego, solo necesita registrarlo como un middleware global para que se ejecute en cada solicitud a su API. En lumen, puede hacerlo agregando la clase en la llamada de middleware dentro de su bootstrap/app.php
$app->middleware([
App\Http\Middleware\RequestsAcceptJson::class
]);
Con Laravel es más o menos el mismo proceso. Ahora el controlador de errores siempre devolverá un json en lugar de texto sin formato/html.
Sé que esta es una pregunta bastante antigua, pero acabo de encontrarla. Por defecto, Lumen devolverá una respuesta JSON si el solicitante la “quiere”.
vendor/laravel/lumen-framework/src/Exceptions/Handler.php:110
return $request->expectsJson()
? $this->prepareJsonResponse($request, $e)
: $this->prepareResponse($request, $e);
esto se reduce a
vendor/illuminate/http/Concerns/InteractsWithContentTypes.php:52
$acceptable = $this->getAcceptableContentTypes();
return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);
Lo que significa que si especifica un encabezado “Aceptar” con lumen “aplicación/json”, automáticamente devolverá una respuesta JSON. p.ej curl -H "Accept: application/json" https://example.com/my-erroring-endpint
Usar esto le evita tener que escribir un controlador de errores personalizado.