Creando respuestas
Cadenas y arreglos
Todas las rutas y controladores deberían devolver una respuesta para ser enviada de regreso al navegador del usuario. Laravel proporciona diferentes formas de devolver respuestas. La respuesta más básica es devolver una cadena desde una ruta o controlador. El framework convertirá la cadena en una respuesta HTTP completa:
Route::get('/', function () { return 'Hello World'; });
Además de devolver cadenas desde tus rutas y controladores, también puedes devolver arreglos. El framework convertirá automáticamente el arreglo en una respuesta JSON:
Route::get('/', function () { return [1, 2, 3]; });
¿Sabías que también puedes devolver colecciones de Eloquent desde tus rutas o controladores? Estas serán convertidas automáticamente a JSON. ¡Inténtalo!
Objetos de respuesta
Típicamente, no sólo estarás devolviendo cadenas básicas o arreglos desde tus acciones de ruta. Además, estarás devolviendo instancias Illuminate\Http\Response
completas o vistas.
Devolver una instancia Response
completa te permite personalizar el código de estado y los encabezados HTTP de la respuesta. Una instancia Response
hereda desde la clase Symfony\Component\HttpFoundation\Response
, la cual proporciona una variedad de métodos para construir respuestas HTTP:
Route::get('home', function () { return response('Hello World', 200) ->header('Content-Type', 'text/plain'); });
Adjuntando encabezados a las respuestas
Ten en cuenta que la mayoría de los métodos de respuestas son encadenables, permitiendo la construcción fluida de instancias de respuesta. Por ejemplo, puedes usar el método header
para agregar una serie de encabezados para la respuesta antes de enviarla de regreso al usuario:
return response($content) ->header('Content-Type', $type) ->header('X-Header-One', 'Header Value') ->header('X-Header-Two', 'Header Value');
O, puedes usar el método withHeaders
para especificar un arreglo de encabezados para que sean agregados a la respuesta:
return response($content) ->withHeaders([ 'Content-Type' => $type, 'X-Header-One' => 'Header Value', 'X-Header-Two' => 'Header Value', ]);
Middleware para control de caché
Laravel incluye un middleware cache.headers
, el cual puede ser usado para rápidamente establecer el encabezado Cache-Control
para un grupo de rutas. Si etag
está especificado en la lista de directivas, un hash MD5 del contenido de la respuesta será automáticamente establecido como identificador del ETag:
Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () { Route::get('privacy', function () { // ... }); Route::get('terms', function () { // ... }); });
Adjuntando cookies a las respuestas
El método cookie
en las instancias de respuesta permite que adjuntes fácilmente cookies a la respuesta. Por ejemplo, puedes usar el método cookie
para generar una cookie y adjuntarla fluidamente a la instancia de respuesta, de la siguiente manera:
return response($content) ->header('Content-Type', $type) ->cookie('name', 'value', $minutes);
El método cookie
también acepta unos cuantos argumentos los cuales son usados con menos frecuencia. Generalmente, estos argumentos tienen el mismo propósito y significado que los argumentos que serán dados al método nativo de PHP setcookie:
->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)
Alternativamente, puedes usar la clase facade Cookie
para agregar cookies a la cola y adjuntarlas a la respuesta saliente de tu aplicación. El método queue
acepta una instancia Cookie
o los argumentos que se necesitan para crear una instancia Cookie
. Estas cookies serán adjuntadas a la respuesta saliente antes de que sea enviada al navegador:
Cookie::queue(Cookie::make('name', 'value', $minutes)); Cookie::queue('name', 'value', $minutes);
Cookies y Encriptación
De forma predeterminada, todos los cookies generados por Laravel son encriptados y firmados de modo que no puedan ser modificados o leídos por el cliente. Si prefieres deshabilitar la encriptación para un subconjunto de cookies generados por tu aplicación, puedes usar la propiedad $except
del middleware App\Http\Middleware\EncryptCookies
, el cual es localizado en el directorio app/Http/Middleware
:
/** * The names of the cookies that should not be encrypted. * * @var array */ protected $except = [ 'cookie_name', ];
Redirecciones
Las respuestas redireccionadas son instancias de la clase Illuminate\Http\RedirectResponse
y contienen los encabezados apropiados que se necesitan para redireccionar al usuario a otra URL. Hay varias formas de generar una instancia RedirectResponse
. El método más simple es usar el helper global redirect
:
Route::get('dashboard', function () { return redirect('home/dashboard'); });
Algunas veces podrás querer redireccionar al usuario a su página previa, tal como cuando un formulario enviado no es válido. Puedes hacer eso usando la función helper global back
. Ya que esta característica utiliza la sesión, asegúrate de que la ruta llamando a la función back
está usando el grupo de middleware web
o tiene todos los middleware de sesión aplicados:
Route::post('user/profile', function () { // Validate the request... return back()->withInput(); });
Redireccionando a rutas nombradas
Cuando ejecutas el helper redirect
sin parámetros, una instancia de Illuminate\Routing\Redirector
es devuelta, permitiendo que ejecutes cualquier método en la instancia Redirector
. Por ejemplo, para generar una RedirectResponse
para una ruta nombrada, puedes usar el método route
:
return redirect()->route('login');
Si tu ruta tiene parámetros, puedes pasarlos como segundo argumento del método route
:
// For a route with the following URI: profile/{id} return redirect()->route('profile', ['id' => 1]);
Rellenando parámetros a través de modelos de Eloquent
Si estás redireccionando a una ruta con un parámetro «ID» que está siendo rellenado desde un modelo Eloquent, puedes pasar el modelo como tal. El ID será extraído automáticamente:
// For a route with the following URI: profile/{id} return redirect()->route('profile', [$user]);
Si prefieres personalizar el valor que es colocado en el parámetro de la ruta, deberías sobrescribir el método getRouteKey
en tu modelo Eloquent:
/** * Get the value of the model's route key. * * @return mixed */ public function getRouteKey() { return $this->slug; }
Redireccionando a acciones de controlador
También puedes generar redirecciones a acciones de controlador. Para hacer eso, pasa el controlador y nombre de acción al método action
. Recuerda, no necesitas especificar el espacio de nombres completo del controlador ya que el RouteServiceProvider
de Laravel establecerá el espacio de nombres del controlador base:
return redirect()->action('HomeController@index');
Si tu ruta de controlador requiere parámetros, puedes pasarlos como segundo argumento del método action
:
return redirect()->action( 'UserController@profile', ['id' => 1] );
Redireccionando a dominios externos
Algunas veces puedes necesitar redireccionar a un dominio fuera de tu aplicación. Puedes hacer eso ejecutando el método away
, el cual crea una instancia de RedirectResponse
sin alguna codificación, validación o verificación de URL adicional:
return redirect()->away('https://www.google.com');
Redireccionando con datos de sesión
El redireccionamiento a una nueva URL y el envío de los datos de la sesión son hechos usualmente al mismo tiempo. Típicamente, esto es hecho después de ejecutar una acción exitosamente cuando mueves rápidamente un mensaje de éxito de la sesión. Por conveniencia, puedes crear una instancia RedirectResponse
y mover rápidamente los datos de la sesión en un solo encadenamiento de método fluido:
Route::post('user/profile', function () { // Update the user's profile... return redirect('dashboard')->with('status', 'Profile updated!'); });
Después de que el usuario es redireccionado, puedes mostrar el mensaje enviado desde la sesión. Por ejemplo, usando la sintaxis de Blade:
@if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif
Otros tipos de respuesta
El helper response
puede ser usado para generar otros tipos de instancias de respuesta. Cuando el helper response
es ejecutado sin argumentos, una implementación del contrato Illuminate\Contracts\Routing\ResponseFactory
es devuelta. Este contrato proporciona varios métodos útiles para generar respuestas.
Respuestas de vista
Si necesitas control sobre el estado y encabezados de la respuesta pero también necesitas devolver una vista como el contenido de la respuesta, deberías usar el método view
:
return response() ->view('hello', $data, 200) ->header('Content-Type', $type);
Ciertamente, si no necesitas pasar un código de estado HTTP o encabezados personalizados, deberías usar la función helper global view
.
Respuestas JSON
El método json
establecerá automáticamente el encabezado Content-Type
a application/json
, al igual que convertirá el arreglo dado a JSON usando la función de PHP json_encode
:
return response()->json([ 'name' => 'Abigail', 'state' => 'CA' ]);
Si prefieres crear una respuesta JSONP, puedes usar el método json
en combinación con el método withCallback
:
return response() ->json(['name' => 'Abigail', 'state' => 'CA']) ->withCallback($request->input('callback'));
Descargas de archivo
El método download
puede ser usado para generar una respuesta que fuerza al navegador del usuario a descargar el archivo a una ruta dada. El método download
acepta un nombre de archivo como segundo argumento del método, el cual determinará el nombre del archivo que es visto por el usuario que esté descargando el archivo. Finalmente, puedes pasar un arreglo de encabezados HTTP como tercer argumento del método:
return response()->download($pathToFile); return response()->download($pathToFile, $name, $headers); return response()->download($pathToFile)->deleteFileAfterSend();
Symfony HttpFoundation, la cual administra las descargas de archivo, requiere que el archivo que esté siendo descargado tenga un nombre de archivo ASCII.
Descargas en streaming
Algunas veces puedes querer convertir la cadena de respuesta de una operación dada a una respuesta descargable sin tener que escribir los contenidos de la operación al disco. Puedes usar el método streamDownload
en este escenario. Este método acepta un callback, un nombre de archivo y un arreglo opcional de encabezados como argumentos:
return response()->streamDownload(function () { echo GitHub::api('repo') ->contents() ->readme('laravel', 'laravel')['contents']; }, 'laravel-readme.md');
Respuestas de archivo
El método file
puede ser usado para mostrar un archivo, tal como una imagen o PDF, directamente en el navegador del usuario en lugar de iniciar una descarga. Este método acepta la ruta del archivo como su primer argumento y un arreglo de encabezados como segundo argumento:
return response()->file($pathToFile); return response()->file($pathToFile, $headers);
Macros de respuesta
Si prefieres definir una respuesta personalizada que puedas volver a usar en múltiples rutas y controladores, puedes usar el método macro
de la clase facade Response
. Por ejemplo, desde un método boot
del proveedor de servicio
<?php namespace App\Providers; use Illuminate\Support\Facades\Response; use Illuminate\Support\ServiceProvider; class ResponseMacroServiceProvider extends ServiceProvider { /** * Register the application's response macros. * * @return void */ public function boot() { Response::macro('caps', function ($value) { return Response::make(strtoupper($value)); }); } }
La función macro
acepta un nombre como su primer argumento y una Closure como segundo. La Closure de la macro será ejecutada al momento de ejecutar el nombre de la macro desde una implementación ResponseFactory
o el helper response
:
return response()->caps('foo');
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.
Lección anterior Solicitudes HTTP - Documentación de Laravel 6 Lección siguiente Vistas - Documentación de Laravel 6