Different ways to use Laravel Form Requests

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 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

/**
 * 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

/**
 * 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() 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.

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.

/**
 * 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.

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

17