Building Advanced Custom Validation Rules in Laravel

Overview of Custom Validation Rules

Repetitive validation logic clutters controllers and makes maintenance a nightmare.

provides a elegant solution through custom validation rule classes. Instead of chaining endless strings in a controller, you encapsulate the logic within a dedicated class. This approach improves code readability and allows you to reuse complex checks across your entire application, from simple format verification to deep API-driven data integrity checks.

Prerequisites

To follow this guide, you should have a solid grasp of

and basic familiarity with the
Laravel
framework. Understanding how dependency injection and class-based programming work will help you navigate the structure of custom rules.

Key Libraries & Tools

  • Laravel Framework: The core environment providing the Rule interface.
  • 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

validator, format isn't enough. We must ensure the video actually exists by querying the API.

$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.

2 min read