La validación por Requests de Laravel 5 es un estilo de validación más avanzado que puede ser reutilizable y nos libera a los controladores de las operaciones de comprobación de la entrada de usuario.
En el artículo anterior del Manual de Laravel estuvimos estudiando una primera vía para construir sistemas de validación de la entrada de usuario. Observamos que es bastante potente, ya que la mayoría de las acciones típicas durante la validación las hace el framework directamente, por lo que nuestro código se queda muy sencillo.
No obstante, todavía puede mejorar la situación. En este artículo explicamos las validaciones por el mecanismo de extender la Request, creando Request especializadas que son capaces no solo de entregar la información del usuario, sino también de validarla convenientemente.
No confundir "Request" en singular con "Requests" en plural. La primera es la que hemos venido usando a lo largo de todo el curso de Laravel, que nos ha proporcionado diversas informaciones y funcionalidades sobre la solicitud del cliente. Esa Request, en singular, siempre está presente en este framework PHP como parte de los recursos que te entregan para realizar tus aplicaciones. Pero por otra parte, nosotros como desarrolladores, podemos crear un número indeterminado de Requests, en plural, para aquellas variantes de entrada de datos que necesite nuestra aplicación.
Las Requests que podemos crear, al extender la Request, disponen de la misma funcionalidad que ya conocemos. Pero además, en esas clases Request que crearemos a partir de ahora vamos a incluir código necesario para las validaciones específicas de ese tipo de entrada. Por ejemplo, una de las Requests podrá ser para validar los datos del usuario, otra para validar datos de un producto, un post, o lo que sea necesario.
Ventajas de la validación por Requests
Son muchos los puntos que mejora este sistema de validación, pero básicamente debemos señalar:
- Separación del código. Es la base de muchos patrones de diseño y nos permite mantener clases más simples, más desacopladas y por tanto de más fácil mantenimiento.
- Reutilización, al poder usar esa misma request en cualquier parte donde estemos recibiendo ese tipo de entrada de usuario. Por ejemplo, cada vez que reciba datos de un usuario podré usar la request del usuario.
Cómo crear una Request personalizada
Existe una carpeta específica para guardar las Requests que creemos para nuestro proyecto, en la ruta "app/Http/Requests".
Además existe un comando de artisan "make:request" que nos hace el trabajo de crear el código base de estas clases para validar una solicitud dada.
php artisan make:request ProductoRequest
Con esto obtendremos una clase llamada ProductoRequest que se sitúa en la ruta de las requests. Su ruta completa por tanto será: "app/Http/Requests/ProductoRequest.php". Si abres este archivo comprobarás que tiene un par de métodos:
class ProductoRequest extends Request
{
public function authorize()
{
return false;
}
public function rules()
{
return [
//
];
}
}
Ambos métodos son para realizar validaciones de la información, pero su responsabilidad es de distinto tipo:
- En la parte de authorize() se comprobará si el usuario está autorizado a realizar esa request. Por ejemplo podrás comprobar si el usuario tiene los permisos adecuados, si aquello que intenta modificar le pertenece y cosas así. Si te fijas, cuando creas el Requests se devuelve un return false, y eso querrá decir que no se le deja pasar.
- En la parte de rules() indicarás las reglas que deben de cumplirse para que se considere que los datos son válidos. Si los campos existen y tienen los valores que se esperan, numéricos, cadenas, de unas dimensiones, etc. Estas reglas de validación son las mismas con las que trabajamos en el anterior artículo sobre validaciones.
Laravel primero hará la comprobación de autorize y luego verá si cumple las reglas que se han indicado en rules().
A continuación tienes el listado de una Requests que hemos creado para el formulario de producto que usamos en el artículo anterior.
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use App\Http\Requests\Requests;
class ProductoRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'nombre' => 'required|max:255',
'descripcion' => 'required|min:10',
'precio' => 'required|numeric',
];
}
}
Como puedes ver, en authorize() hemos colocado de momento un return true;. Esto producirá que siempre se autorice a realizar esta acción. Más adelante escribiremos alguna cosa en este método.
Por su parte, en rules() tenemos las mismas reglas de validación que ya conocemos, en el array que se devuelve.
Cómo usar una de nuestras Requests personales
Después de crear una requests podemos usarla en el controlador. Solo necesitamos realizar dos tareas:
Primero agregar el "use" correspondiente para que se conozca el nombre de la clase ProductoRequest.
use App\Http\Requests\ProductoRequest;
Luego podremos usar esa clase en la cabecera de los métodos que deban realizar la validación de la entrada de datos.
public function store(ProductoRequest $request)
{
echo 'Estoy usando la Request personalizada ProductoRequest. ';
echo 'No necesito invocar explícitamente las funciones para validar. ';
echo 'Si estoy aquí sé que los datos están validados.';
dd($request->all());
}
Como puedes ver, al definir el método store() colocamos el parámetro que ahora se especifica con el nombre de nuestra request personalizada: ProductoRequest.
Laravel ya se encarga por su cuenta de llamar a los procedimientos de validación automáticamente, sin que tengamos que intervenir. Si no pasa la validación realizará una de estas dos acciones:
- Si no pasa el authorize() mostrará un "Forbidden". Este tipo de error se supone que será por una acción no permitida a nivel de aplicación y teóricamente porque están queriendo hacer alguna cosa, burlando la seguridad. Por ello no se realiza un tratamiento especial, mostrando simplemente un feo mensaje que no da muchas pistas al usuario de lo que pueda estar pasando.
- Si no pasa el rules() hace lo mismo que el método validate cuando no se pasan las reglas, es decir, redirige a la página anterior flasheando la entrada de datos a la sesión y generando los errores de validación para que luego podamos mostrarlos, bien claritos para ayudar al usuario a localizar los problemas en la entrada de datos. Para más aclaraciones consulta el anterior artículo de introducción a las validaciones.
Luego, cualquier código dentro del método se ejecutará solamente si las validaciones pasaron correctamente. Así que el método del controlador nos queda liberado de cualquier proceso de validación y podemos escribir solo el código de los procesos necesarios para ejecutar las acciones deseadas.
Además, dentro del método del controlador podemos usar tranquilamente el objeto de la clase ProductoRequest como si fuera un objeto de la clase Request normal, ya que la clase ProductoRequest hereda de Request. Podremos acceder a los datos de usuario y a todas las otras operaciones que hay en un Request de las que ya conocemos.
En todos los controladores que necesitemos validar la entrada de datos podremos hacer el mismo procedimiento para validar implícitamente, usando el Requests creado para el caso. Por tanto, no es necesario repetir el código de validaciones en varias partes de la aplicación y se produce la reutilización.
Qué sentido tienen las validaciones en el controller
Si has apreciado lo limpios que quedan nuestros controladores con este estilo de validación y valoras positivamente la separación del código y la reutilización de las funciones de validación, quizás te preguntarás ¿Y entonces para qué necesito, o qué sentido tienen, las validaciones en el controller que vimos en el artículo anterior?
Bueno, la verdad es que continúan siendo útiles en varios casos, primero y menos importante es que en determinado momento puede que nos resulte más cómodo realizar una validación sencilla de alguna cosa en el controlador, sin que tengamos que generar una nueva clase para realizar algo rápidamente.
Pero la razón de más peso es que hay acciones que pueden requerir validaciones más especializadas. Por ejemplo al crear una factura podemos validar una serie de informaciones básicas. Pero quizás al editarla hay otra serie de reglas que se deben comprobar. En ese caso, esas validaciones específicas tenemos que colocarlas en la acción del controlador que las necesita.
De momento es todo, esperamos que aprecieis la potencia y simplicidad de este nuevo método de validar y lo podáis practicar.
Carlos Ruiz Ruso
Consultor tecnológico para el desarrollo de proyectos online especializado en Wo...