You are on page 1of 9

Get started Open in app

KashYap Merai

Follow 196 Followers About

😎
The Smart Way To Handle Request Validation
In Laravel
KashYap Merai May 28, 2018 · 3 min read

“black and white portrait of a man in Medieval armor, getting ready to swing a sword.” by Henry Hustava on Unsplash

Laravel is PHP framework for web artisan. Which helps us to build robust application
and APIs. As many of you already know there are many ways to validate request in
Laravel. Handling request validation is very crucial part of any application. Laravel has
Get started Open in app
some great feature which deals with this very well.

Get Started
Most of us are familiar with using the validator in the controller. And it’s most common
way to handle validation for the incoming request.

Here’s how our validator looks like in UserController

1 <?php
2
3 namespace App\Http\Controllers\API\v1\Users;
4
5 use App\Http\Controllers\Controller;
6 use Illuminate\Http\Request;
7 use Illuminate\Support\Facades\Validator;
8 use App\Entities\Models\User;
9
10 class UserController extends Controller
11 {
12 public function store(Request $request)
13 {
14
15 // validate incoming request
16
17 $validator = Validator::make($request->all(), [
18 'email' => 'required|email|unique:users',
19 'name' => 'required|string|max:50',
20 'password' => 'required'
21 ]);
22
23 if ($validator->fails()) {
24 Session::flash('error', $validator->messages()->first());
25 return redirect()->back()->withInput();
26 }
27
28 // finally store our user
29
30 }
31 }
Validation in controller

There’s nothing wrong with validating incoming request in the controller but it’s not
the best way to do this and your controller looks messy. This is bad practice in my
opinion. The controller should do only one thing handle request from the route and
Get started Open in app
return an appropriate response.

Writing validation logic in the controller will break The Single Responsibility
Principle. We all know that requirements changes over time and every time
requirement get change your class responsibilities is also change. So having many
responsibilities in single class make it very difficult to manage.

Laravel has Form Request, A separate request class containing validation logic. To
create one you can use below Artisan command.

php artisan make:request UserStoreRequest

Which will create new Request class in app\Http\Request\UserRequest

1 <?php
2
3 namespace App\Http\Requests;
4
5 use Illuminate\Foundation\Http\FormRequest;
6
7 class UserStoreRequest extends FormRequest
8 {
9 /**
10 * Determine if the user is authorized to make this request.
11 *
12 * @return bool
13 */
14 public function authorize()
15 {
16 return true;
17 }
18
19 /**
20 * Get the validation rules that apply to the request.
21 *
22 * @return array
23 */
24 public function rules()
25 {
26 return [
27 'email' => 'required|email|unique:users',
28 ' ' ' i d| t i | 50'
28 'name' => 'required|string|max:50',
29 'password' => 'required'
Get started Open in app
30 ];
31 }
32
33 /**
34 * Custom message for validation
35 *
36 * @return array
37 */
38 public function messages()
39 {
40 return [
41 'email.required' => 'Email is required!',
42 'name.required' => 'Name is required!',
43 'password.required' => 'Password is required!'
44 ];
45 }

Laravel Form Request class comes with two default methods auth() and rules() . You

can perform any authorization logic in auth() method whether the current user is
allowed to request or not. And in rules() method you can write all your validation
rule. There’s one additional method messages() where you can pass your own
validation messages array.

Now change our UserController to use our UserStoreRequest. You can type-hint our
request class and it will automatically resolve and validate before our controller
function called.

1 <?php
2
3 namespace App\Http\Controllers\API\v1\Users;
4
5 use App\Http\Controllers\Controller;
6 use App\Http\Requests\UserStoreRequest;
7
8 class UserController extends Controller
9 {
10 public function store(UserStoreRequest $request)
11 {
12 // Will return only validated data
13
14 $validated = $request->validated();
15 }
16 }
6 }

Get started Open in app

So our controller is now slim and easy to maintain . Now our controller doesn’t need to
worry about any validation logic. We have our own validation class with only one
responsibility to handle validation and let controller do there work.

If validation fails, it will redirect the user to the previous location with an error.
Depends on your request type error message will be flash in sessions. If the request was
an AJAX then a response with 422 status code will be return with an error in JSON
format.

✨ Bonus
Keep your application and your User safe by sanitizing inputs. Using sanitizers in your
application it’ll ensure you that data is always well-formatted and consistent. In many
cases validation failed due to silly formatting mistakes.

A User entered a mobile number like this +99–9999–999999 or +99-(9999)-


(999999). It’s very common error to make for that we can’t force our user to re-enter
the same details again.
Some other examples are a user entered an email as Foo@Bar.COM or FOO@Bar.com.
Get started Open in app
Or type first name and last name like FOO bAR or foo baR

Sanitizer contains methods for transforming and filtering our data in common format
before providing to the validator.

I’m using Waavi/Sanitizer package which has many filters.

Waavi/Sanitizer
Sanitizer - Data sanitizer and form request input sanitation for
Laravel 5.
github.com

Let’s create BaseFormRequest abstract class for our Form Request and use
SanitizesInput trait here.

1 <?php
2
3 namespace App\Http\Requests;
4
5 use Illuminate\Contracts\Validation\Validator;
6 use Illuminate\Foundation\Http\FormRequest;
7 use Illuminate\Http\Exceptions\HttpResponseException;
8 use Illuminate\Http\JsonResponse;
9 use Waavi\Sanitizer\Laravel\SanitizesInput;
10
11 abstract class BaseFormRequest extends FormRequest
12 {
13 use SanitizesInput;
14
15 /**
16 * For more sanitizer rule check https://github.com/Waavi/Sanitizer
17 */
18 public function validateResolved()
19 {
20 {
21 $this->sanitize();
22 parent::validateResolved();
23 }
24 }
25
26 /**

Get started* Get Open


27 in app
the validation rules that apply to the request.
28 *
29 * @return array
30 */
31 abstract public function rules();
32
33 /**
34 * Determine if the user is authorized to make this request.
35 *
36 * @return bool
37 */
38 abstract public function authorize();
39

So now we can write our UserStoreRequest like below. Extend your Form Request from
our base class so we don’t have to include trait in all request classes.

1 <?php
2
3 namespace App\Http\Requests;
4
5 class UserStoreRequest extends BaseFormRequest
6 {
7 /**
8 * Determine if the user is authorized to make this request.
9 *
10 * @return bool
11 */
12 public function authorize()
13 {
14 return true;
15 }
16
17 /**
18 * Get the validation rules that apply to the request.
19 *
20 * @return array
21 */
22 public function rules()
23 {
24 return [
25 'email' => 'required|email|unique:users',
26 'name' => 'required|string|max:50',
27 'password' => 'required'
28 ];
29 }
29 }
30
Get started Open in app
31 public function messages()
32 {
33 return [
34 'email.required' => 'Email is required!',
35 'name.required' => 'Name is required!',
36 'password.required' => 'Password is required!'
37 ];
38 }
39
40 /**
41 * Filters to be applied to the input.
42 *
43 * @return array
44 */
45 public function filters()
46 {
47 return [
48 'email' => 'trim|lowercase',
49 'name' => 'trim|capitalize|escape'
50 ];
51 }

SanitizesInput trait provides a method filters() for formatting our request data
before providing to the validator. filters() method return array of valid filters. Here
we converting user email to lowercase and trimming same way converting name to
uppercase and escape any HTML tags.

You can read more about available filters from here.

Conclusion
At first, it seems unnecessary to make separate request class for all. But imagine
putting all your validations logic in the same controller. It’s like a terrible nightmare 👻
when it’s come to manage your code and worst if someone else has to manage it 😛.
Thank you for reading.

I’d like to hear your views on it. If you have any questions or suggestion please leave the
comment below.

Have a wonderful day.


Get started Open in app
Laravel Validation Programming Laravel 5 Form Request

About Write Help Legal

Get the Medium app

You might also like