Creating A Custom Form Request In Laravel

Laravel

Laravel does an incredible job helping developers break their code into smaller parts, which reduces code clutter and makes the code easier to read. I recently discovered how to create a custom form request for handling validation during a form submission.

Before a custom form request

Let’s pretend we have created a Product model and want to update the name or price fields. A ProductController::update() method will handle the update form submission

Before using a custom form request, the ProductController::update() method may look like the following.

/**
 * Update the specified resource in storage.
 *
 * @param \Illuminate\Http\Request $request
 * @param \App\Product $product
 * @return \Illuminate\Http\Response
 */
public function update(Request $request, Product $product)
{
    $this->validate($request, [
        'name' => 'required|max:255',
        'price' => 'required|numeric',
    ]);

    $product->update(
        $request->only('name', 'price')
    );

    return back()->with('status', 'The product was updated!');
}

This is pretty basic and easy to read. However, the ProductController::update() method could grow as the application requires more complexity. By moving the validation into it’s own class, we can help reduce code complexity.

Creating the custom request

Using an artisan command, create a custom request.

$ php artisan make:request ProductUpdateRequest

This will create the ProductUpdateRequest.php file within the app/Http/Requests directory.

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ProductUpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}

The ProductUpdateRequest::authorize() method will determine if the request can be validated in the first place. This is a good place to check if the user is logged in and if the user has the capability to make the update. For this example, the ProductUpdateRequest::authorize() method will just return true.

The ProductUpdateRequest::rules() method will return the validation rules for the current request.

Copy the validation rules from the ProductController::update() method to the ProductUpdateRequest::rules() method.

The custom request class should look like the following.

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ProductUpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|max:255',
            'price' => 'required|numeric',
        ];
    }
}

The ProductController::update() method can now have a ProductUpdateRequest type-hint for the $request parameter and the validation inside can be removed.

use App\Http\Requests\ProductUpdateRequest;

/**
 * Update the specified resource in storage.
 *
 * @param \App\Http\Requests\ProductUpdateRequest $request
 * @param \App\Product $product
 * @return \Illuminate\Http\Response
 */
public function update(ProductUpdateRequest $request, Product $product)
{
    $product->update(
        $request->only('name', 'price')
    );

    return back()->with('status', 'The product was updated!');
}

Since ProductUpdateRequest inherits from FormRequest, Laravel will know to inject the class as the $request parameter as well as run the authorize and validation logic before hand. If the validation fails, Laravel will return the user to the form with the errors.

Check out the Laravel documentation for more information and a guide on creating custom request classes.

Have anything to add that I missed? Let me know.

Author: rfmeier

Product developer at WPEngine and runner from Schaumburg, Illinois. I work with php and Python; Spending most of my time digging into source code to see how it all works.