Porque devo usar Form Request no Laravel

O Laravel é uma ferramenta cada vez mais completa e fornece aos desenvolvedores formas simples de acessar e criar quase tudo o que podes imaginar. Não fizeste include com use ou não adicionaste “\” antes de usar uma Facade? Sem problema, o Laravel permite-te usar as helper functions para cada uma, tais como app, session, cache, etc… O mesmo se aplica com as validações. Existem várias formas que podes usar para validar os teus requests.
<?php
// namespaces and use statements are left intentionally :)
class User extends Controller {
public function create(Request $request)
{
// When making a validator instance using make, remember to pass $request data array
$validate = Validate::make($request->all(), [
// your rules
], [
// messages
])->validate();
// OR
$this->validate($request, [
// Your rules
], [
// messages
]);
// OR
$request->validate(, [
// Your rules
], [
// messages
]);
}
}
Diferentes formas de fazer a validação. No entanto não gosto muito da ideia de validar os form request nos controladores (não que tenha mal algum, simplesmente EU não gosto). Os Controladores devem fazer tarefas que lhe são pedidas. Se a rota pede para criar um novo user, então o resspetivo méodo do controlador deve criar um novo user e retornar a resposta. O Laravel proporciona a possibilidade de criarmos os nossos próprios form requests para as validações dos request data antes de eles chegarem ao controlador. Verifica na documentação oficial. Para criar o teu form request executa o seguinte comando:
php artisan make:request CreateUser
Por defeito existem dois métodos na class do request. No método authorize() podemos autenticar o user que pode executar a ação ou não e no método rule() apenas irá ser retornado um array com as rules que precisam ser implementadas. Vamos dar uma vista de olhos num exemplo onde seja necessário implementar as nossas próprias rules para validação. Existem muitas formas para criarmos as nossas rules mas iremos usar uma validation factory para esse propósito. Vamos ver o que podemos fazer sem um form request customizado para alterar a password do user logado na aplicação.
<?php
// .. class code
public function changePassword(Request $request){
$request->validate([
'old_password' => 'required|min:6|max:40' // Setting maximum length for passwords is a good idea imo.
'password' => 'required|min:6|max:40|confirmed'
]);
if(Hash::check($request->input('old_password'), $request->user()->password)){
// change the password and return the response
}
// return the response stating that old password did not match
}
Vamos agora criar o Form Request para limparmos o Controller
php artisan make:request ChangePasswordRequest
Depois de criada a class ChangePasswordRequest terá o seguinte código:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Factory;
class ChangePasswordRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
// you can authorize the request if user can change his password or not.
// This will be useful in the scenario where only admin can change it
// so you can check here whether the user is admin or not
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'old_password' => ['required', function ($attribute, $value, $fail) {
if (!\Hash::check($value, $this->user()->password)) {
$fail('Old Password did not match to our records.');
}
}],
'password' => 'required|min:6|max:40|confirmed'
];
}
}
Ao definirmos as rules, temos que definir uma regra para verificarmos a password antiga (old_password) usando uma closure function. Podemos definir as nossas próprias regras registando em AppServiceProvider ou podemos usar uma class separada para fazermos extend na class Rule. Outras duas opções são geralmente melhores quando tens de usar a mesma regra várias vezes para diferentes requests.
<?php
// .. class code
public function changePassword(ChangePasswordRequest $request){
// change the password and return the response
}
Código limpo e apenas com uma tarefa para fazer. Não precisamos preocupar-nos com a validação ou uqalquer outra coisa. A class ChangePasswordRequest terá a responsabilidade de validar o request que chegar ou redirecionará para trás com erro. No caso de estar a ser usado API retornará um JSON com os erros com o código 422.
Conslusão:
Na minha opinião o controller deve fazer o trabalho para o qual foi criado. Esta é uma boa prática para evitarmos código desorganizado e torná-lo limpo e legível. Imagina um controlador onde seja necessário aplicarmos validações condicionais. Li este excelente artigo de Matthew Erskine onde fala de validações condicionais realmente fez-me ver que existem coisas que podem ser feitas de uma forma mais elegante e limpa. Presta atenção às formas como podes melhorar o teu código e forma de programar.
E é isto! Alguma duvida comenta abaixo ou entra em contato comigo nos canais disponibilizados neste site. Sugestões são sempre bem vindas ou mesmo pedidos sobre temas que gostavas de ver abordados neste blog.