Building Advanced Custom Validation Rules in Laravel
Overview of Custom Validation Rules
Repetitive validation logic clutters controllers and makes maintenance a nightmare.
Prerequisites
To follow this guide, you should have a solid grasp of
Key Libraries & Tools
- Laravel Framework: The core environment providing the
Ruleinterface. - YouTube API: Used to verify the actual existence of video data beyond just URL formatting.
- HTTP Client (Guzzle): Typically used within the rule to perform external requests.
Code Walkthrough: Implementing Logic
Creating a rule involves defining a class that implements the ValidationRule interface. The core logic lives inside the validate method.
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (!filter_var($value, FILTER_VALIDATE_URL)) {
$fail("The {$attribute} must be a valid URL.");
}
}
In the example above, we first check if the input is a valid URL. If it fails, we trigger the $fail closure. However, for a
$response = Http::get("https://www.googleapis.com/youtube/v3/videos", [
'id' => $videoId,
'key' => config('services.youtube.key'),
]);
if ($response->json('pageInfo.totalResults') === 0) {
$fail('This YouTube video does not exist.');
}
Syntax Notes and Best Practices
Laravel's modern validation rules use the validate method which receives a $fail callback. This is a shift from older versions that returned a boolean. Always use the $attribute variable in your error messages to keep them dynamic. For external API calls, remember to handle timeouts so your validation doesn't hang the application.
Practical Examples
Beyond video verification, use this pattern for checking if a username is on a restricted list, verifying international tax IDs via external lookup services, or ensuring a file upload meets specific proprietary metadata requirements that standard validators can't catch.
