DEV Community

Cover image for Different ways to use Laravel Form Requests
Othmane Nemli
Othmane Nemli

Posted on • Updated on

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
    ];
}
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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

 ];
}
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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

Top comments (11)

Collapse
 
ayoubbousetta profile image
AYOUB BOUSETTA

Not bad, but i guess it's a little bit over-engineered

Collapse
 
othmane_nemli profile image
Othmane Nemli

It just depend on how you want to structure your project.

Collapse
 
muhammadmp profile image
Muhammad MP

I prefer to create another form request class for the update method.

Collapse
 
bowie profile image
Bowie

+1 to this. I've created two classes both extending the FormRequest class for this. Alternatively you could create a super class in between for inheritance. While the proposed method in this article isn't bad, I prefer this method personally

Collapse
 
jovialcore profile image
Chidiebere Chukwudi

This!...

Collapse
 
franciscocaldeira profile image
Francisco

what about authorize()? for the store(), update(), destroy(), view() ?

Collapse
 
arerex profile image
Arif Zuhairi

Thank you Othmane, this is really good writeup for me to understand, maybe just some little typos in 1st & 3rd pictures, I think

Collapse
 
othmane_nemli profile image
Othmane Nemli • Edited

It's my pleasure that was helpful for you.. and thank you for pointing the typos :)

(y)

Collapse
 
sahandi81 profile image
Sahand RahmatPanah

ok, thats good. i want to call $controller->store() manually. how can i create request for store method ???

Collapse
 
camohub profile image
camo

Why this does not work inside form request?
$this->input('notification_type_id', null) // Always returns null

Collapse
 
mubarak profile image
Ahmed Mubarak

Such a great article, but I was wondering how to pass data like route parameters into the form request, I tried many techniques as per Laravel docs but unluckily did not work for the form request.