Write Your Laravel Validation Logic Like a Senior Dev, Part 1
Separating validation from your controllers with Form Requests

I am a full-stack web developer that enjoys coding in Laravel and React.
Search for a command to run...
Separating validation from your controllers with Form Requests

I am a full-stack web developer that enjoys coding in Laravel and React.
No comments yet. Be the first to comment.
Here I will post some articles that help devs with simple and complex topics in Laravel.
Making custom rules when they get complicated
Switching stacks

If you don't know what Twin Macro is, check it out! It's a great library that blends Tailwind CSS and Styled Component systems, like Emotion. I love using Twin because it lets me use Tailwind while separating my styling from my markup and methods. If...

Many developers know that full-stack apps with a Vue frontend can be quickly spun up with Laravel Jetstream. What many don’t know is that recently, the Laravel team made it easy to make an Inertia app with Laravel Breeze. In this article, we'll make ...

Extending the Rule Object with a DateTime Trait

Using Custom Console Commands

Laravel senior devs are constantly looking for ways to ensure their functions, especially their controller methods, are DRY and only do one thing. Laravel provides many easy and intuitive ways to refactor your controllers to make them highly readable and maintainable. Laravel has one nifty feature called Form Requests, which are custom request classes that contain validation and authorization logic. This is the first of a three- (or more) part series to show how we can take advantage of Laravel features to make Validation more powerful.
Preliminaries:
php artisan serveFirst Steps: Because we're working with an API, we'll need to create custom validation Exceptions. As it stands now, Laravel will return HTML every time we get a validation error.
php artisan make:request ApiFormRequest. This will create a file that can be found at app/Http/Requests/ApiFormRequest.php.failedValidation() method. However, because we want to reuse it for our other Form Requests, we'll make ApiFormRequest an abstract class. We'll remove the bodies of our authorize() and rules() methods and make them abstract so that we don't end up clashing or overriding them. <?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
abstract class ApiFormRequest extends FormRequest
{
abstract public function authorize();
protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json([
'errors' => $validator->errors()
], 422));
}
abstract public function rules();
}
The Work Begins:
php artisan make:request RegisterRequest.ApiFormRequest instead of FormRequest to use its methods.<?php
namespace App\Http\Requests;
use App\Http\Requests\ApiFormRequest;
class RegisterRequest extends ApiFormRequest
{
//
}
authorize() to return false. Do not forget to set this to true, or you will get "Unauthorized" errors that may trip you up. NB: You can also define custom logic for your authorize() method but that's for another day.The Work Continues:
name, email, and password. NB: Each value can be an array instead of a string. This comes in handy when we're making custom rules.<?php
namespace App\Http\Requests;
use App\Http\Requests\ApiFormRequest;
use App\Rules\StrongPassword;
class RegisterRequest extends ApiFormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8',
];
}
$request parameter passed into your controller's method. <?php
namespace App\Http\Controllers;
use App\Http\Requests\RegisterRequest;
use Illuminate\Support\Facades\Hash;
use App\Models\User;
class RegisterController extends Controller
{
public function __invoke(RegisterRequest $request){
$validated = $request->validated();
...
}
$validated variable. Our validated data is in an array, not an object, so to access the validated email data, for instance, we use validated['email']. NB: Laravel recommends doing it this way but you'll still be able to use the $request object if your validations pass.The Work Ends:
password too short. Whatever you do, try to get a negative response from the API. Here's what I did and the response I got:
rules() method, add another method called messages().rules() method where you'll return an associative array. The difference is that the keys are named a bit differently, and your values will be the messages for each rule.public function messages(){
return [
'name.max:255' => 'Your name is too long :/',
'email.email' => 'Please ensure that your email address is in the correct format',
'email.max:255' => 'Your email address is too long :/',
'email.unique:users' => 'This user already exists',
'password.required' => 'Please enter a valid password'
];
}
Conclusion: