Paulund
2017-10-03 #laravel

How To Validate Requests In Laravel

When it comes to validation in Laravel there are several ways you can go about this. In this tutorial we're going to investigate the different ways you can achieve this in Laravel and I'll go through my opinion on the best approach to take when validating requests.

What Are The Different Options?

As I said there are multiple ways we can validate the request on creating or updating a model so what are these options. The simplest option is to use the validate() method on your controller, or you can use the validate() method on the request object itself. The other option is to use a Form Request object to validate the request automatically on any methods you choose. In this tutorial we're going to show how you can use both of these approaches in your application.

Controller

In this example we're going to work within a controller for creating posts on a blog. This is going to the have the 4 methods we need to create a new blog post and methods to handle the editing an existing blog post. To create a new blog post we're going to use the create method to display the view of the new blog post form. Then when we submit the form we need to post this to the store method. To update the blog post we're going to use the edit method to display the edit view of the existing blog post. Then on submit of the form we need to put this to the update method.

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class PostController extends Controller
{
    public function create()
    {
        return view('post.create');
    }

    public function store()
    {
        
    }

    public function edit($id)
    {
        return view('post.edit');
    }

    public function update($id)
    {
        
    }
}

Using Validate Method On Your Controller

To use the validate method in your controllers you need to add the ValidatesRequests trait to your controller or your base controller. Now you'll be able to pass in the Request object and the rules you want this request to follow to return the valid data.


public function store(Request $request)
{
    $data = $this->validate($request, [
       'post_title' => 'required',
       'post_content' => 'required',
    ]);

    // Valid data
}

In Laravel 5.5 a feature was added to return the valid data from the validate method. ## Using The Validate Method On The Request

On the object Illuminate\Http\Request, there is a validate() method that you can use to validate the data inside the object. It works in a similar way to the above but it's a bit nicer to read.


public function store(Request $request)
{
    $data = $request->validate([
       'post_title' => 'required',
       'post_content' => 'required',
    ]);

    // Valid data
}

Using Form Request Objects

The other option to use on your validation is to use form request objects. You can create new request objects by using the artisan command php artisan make:request. This will create a new object inside the folder App\Http\Requests. On this request object you'll get 2 methods by default authorize and rules. The authorise method can be used to make sure that the current logged in user has the rights to create new posts.


/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
    return $this->user()->can('create-posts');
}

Then in the rules method you can add the rules for your blog post.


/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'post_title' => 'required',
        'post_content' => 'required',
    ];
}

Therefore the Form Request object will look something like this.


namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreatePost extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return $this->user()->can('create-posts');
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'post_title' => 'required',
            'post_content' => 'required',
        ];
    }
}

With this object we can now use this in our store method and on injecting the request object Laravel will automatically validate the request which makes sure everything is valid inside the method, therefore now the store method will look like this.


public function store(CreatePost $request)
{
    // Valid data
}

Using Validated Data

Now we know that the request is valid we can use the request data in our method there are a few ways we can do this. From the $request object you'll have access to two main methods all() and only(). All will return all the data in the request object. This makes it very easy to get all the data you need but because it will just grab everything it will also bring back data that you don't need. This is where the only method comes into play, this will accept an array of the parameters that you want to return and it will only return this data from the request object.


$all = $request->all();

$only = $request->only([
    'post_title',
    'post_content'
]);

There is a third method that not many people are aware of, this is the validated() method, this is the best option of the three choices as it will return all data points that have been validated from your form requests.


public function store(CreatePost $request)
{
    // Valid data
    $data = $request->validated();
}

This method will grab all the options in the rules array and pass this into the only() method to only return the data that was validated correctly.

Which One To Use?

With all these options on validating a request and handling your data, which one should you use? The simplest option is to just call this directly in your controller using the validate() method on the request object. But for this simplicity you're not using some powerful features that come included with the form request object, this is why my primary method is to use a Form Request object.

This allows me to add an authorise method to the incoming request to make sure the user has the right access to do the request.

The next benefit is that your rules logic is based in one location to handle the same request. Therefore if you want to validate this request in another controller you can easily reuse this object to do that.

The third benefit is it keeps the controller code simple, you don't have to worry about validating the data, everything you do in the controller you can just assume the data is already valid.

The fourth benefit is the use of that validated() method being able to only return data that has passed validation you know you're working all with clean data. This is what I use, would be great to hear your thoughts and you can contact me on Twitter with your thoughts.