Different ways to use Laravel Form Requests
Tags: laravel, php, validation
Published: 2021-06-29 11:25:18

Laravel provides several different approaches to validate your application’s incoming data. It is most common to use the validate method available on all incoming HTTP requests. However, in this topic, we will use [Form Requests](https://laravel.com/docs/8.x/validation#form-request-validation "Form Requests") in different ways.

First of all, I don’t think using a small validation in the controller will harm your code readability but on the other hand, if you are willing to handle more complex validation scenarios, you may wish to create a “Form Request“.

Form requests are custom request classes that encapsulate their own validation and authorization logic.

Let’s create our own form request class, all you need is to run this command:

`php artisan make:request StoreUserRequest`

A new `StoreUserRequest` class will be generated under "*\App\Http\Requests*" namespace containing a **rules()** & **authorize()** methods.
Let’s add some quick validation under **rules()** method

```php
/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'name' => 'required|min:3|max:50',
        'email' => 'required|email|unique:users',
        'password' => 'required|confirmed|min:8',
        //... more validation
    ];
}
```
After that, we will inject our new Form request in the controller **store()** method
```php
/**
 * Store a new user.
 *
 * @param  \App\Http\Requests\StoreUserRequest  $request
 * @return Illuminate\Http\Response
 */
public function store(StoreUserRequest $request)
{
    // The incoming request is valid...

    // Retrieve the validated input data...
    $validatedData = $request->validated();
}
```
So far so good, if the validation is valid we will get our validated data from Form request otherwise a Validation Exception will be thrown.

Now, what about the update, clearly we need to use another form request `UpdateUserRequest` with its rules and inject it in the controller **update()** method.

So this is the first and the simple approach used so far.

------------


The second approach is using one class to handle the store and update rules, so, we will run the command again and create new Form Request by naming it `UserRequest`.

We create **store()** and **update()** functions and call them in **rules()** function by using [isMethod()](https://github.com/symfony/symfony/blob/e34cd7dd2c6d0b30d24cad443b8f964daa841d71/src/Symfony/Component/HttpFoundation/Request.php#L1457 "isMethod()")  we're checking the HTTP request method if is it a *POST* or other than that, you may be specific and check if it is a *PUT/PATCH*.

As you may notice we can also share validations used in both methods and concatenate it with the proper validation function.

```php
public function rules()
{
 return ['name' => 'required|min:3|max:50']
 +
 ($this->isMethod('POST') ? $this->store() : $this->update());
}

protected function store()
{
 return [
 'email' => 'required|email|unique:users',
 'password' => 'required|confirmed|min:8',
 //… more validation
 
 ];
}

protected function update()
{
 return [
 'email' => 'required|email|unique:users,email,'.$this->user()->id,
 'logo' => 'nullable|image|max:1024',
 'bio' => 'nullable|max:300',
 'github_url' => 'nullable|url'
 //… more validation
 
 ];
}
```
After that, we will inject  `UserRequest`  in both **store()** and **update()** methods.
Now, we have one class that serve different validation depends on HTTP request.

```php
/**
 * Store a new user.
 */
public function store(UserRequest $request)
{
 $validated = $request->validated();
}
/**
 * Update user.
 */
public function update(UserRequest $request)
{
 $validated = $request->validated();
}
```

------------


I will name the third approach “ResourceFormRequest” and it will be a little bit different from the others.

First I’ll create a `BaseFormRequest` that contains all resourceful methods, feel free to use your own naming just be careful when you name your methods to not end up overriding Request class methods.

After that, create `UserRequest` and extends `BaseFormRequest`, and override existing methods with your rules, finally inject the UserRequest inside your controller methods.

{% gist https://gist.github.com/PsyLogic/13ca483a6629d34b27e768b08ee27a3f %}

Our Resource Form Request can handle now a Controller resource and you end up with one file that manage all validations of specific Model instead of separate files which personally I don't like it.

I think there's a lot of approaches that we can follow and feel free to share your best approach or other approaches you have.

Finally, if you are reading this line I think the topic was interesting for you.

Thank you