Laravel Validation: Mastering Custom Rules & Best Practices

how to create and apply validation rules in laravel

Laravel validation plays a crucial role in ensuring that user input is accurate, secure, and reliable. It prevents common security issues like SQL injection and malformed data while maintaining data integrity.

In this blog, we’ll learn how to create custom validation rules for more complex scenarios. We’ll also learn the best practices followed by Laravel development experts for implementing validation. Additionally, we’ll dive into testing custom validation rules to ensure they work as expected. With that said, let’s dive in.

Understanding Laravel’s Built-In Validation

Laravel provides a robust validation system out of the box, making it simple to validate user input with minimal effort. Built-in validation rules cover a wide range of scenarios, including ensuring required fields, enforcing formats like email addresses, or setting constraints such as minimum and maximum lengths. These features simplify the development process and enhance the reliability of your application.

Laravel’s built-in validation is designed to be intuitive and highly readable. Let’s start by looking at a common example:

$request->validate([
    'email' => 'required|email',
    'password' => 'required|min:8',
]);

In the above code:

  • required: Ensures the field is not empty.
  • email: Checks if the input is a valid email address.
  • min:8: Ensures that the password is at least 8 characters long.

Understanding these basics of Laravel’s built-in validation sets the foundation for mastering custom rules, which we’ll explore next.

Creating Custom Validation Rules in Laravel

While Laravel’s built-in validation rules cover most scenarios, there are times when you need to implement logic specific to your application’s requirements. Laravel makes it simple to create custom validation rules, ensuring your validation logic is both reusable and maintainable.So, let’s dive into how you can create custom validation rules: using closures, rule objects, and custom validation services.

Using Closure-Based Rules

Closure-based rules are the easiest and quickest way to define one-off validation logic. These rules are ideal for simple checks that don’t require reusability. You define the validation logic inline within your validate method. Here is the example code:

$request->validate([
    'username' => [
        'required',
        function ($attribute, $value, $fail) {
            if (str_contains($value, 'admin')) {
                $fail($attribute.' should not contain the word "admin".');
            }
        },
    ],
]);

In the above code:

  • $attribute: Represents the name of the field being validated (e.g., username).
  • $value: Contains the value of the field (e.g., the input provided by the user).
  • $fail: A callback function to trigger a validation error with a custom error message.

When to Use: Use closure-based rules are perfect for quick validation checks. It is also perfect for scenarios where the logic isn’t reused elsewhere in the application.

Using Rule Objects

If you find yourself repeating a validation rule or need to make it more structured, consider using a Rule Object. This approach encapsulates validation logic into a dedicated class, making your code cleaner and easier to manage. Run the following Artisan command to generate a new rule class:

php artisan make:rule Uppercase

This will create a file in the app/Rules directory. Customize it to define your validation logic:

namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Uppercase implements Rule
{
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value; // Checks if the value is entirely uppercase
    }
    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}

To apply this rule in your validation logic:

use App\Rules\Uppercase;
$request->validate([
    'username' => ['required', new Uppercase],
]);

When to Use: Opt for rule objects when you need reusable and structured validation logic.

Using Custom Validation Services

For complex validation logic that needs to be used in multiple places across your application, creating a custom validation service is the best approach. This method uses Laravel’s service container to inject reusable validation logic.

Step 1: Create the Service Class

Define a custom validation service in the app/Services directory:

namespace App\Services;
class UsernameValidator
{
    public function validate($value)
    {
        return !str_contains($value, 'admin'); // Rejects usernames containing "admin"
    }
}

Step 2: Register the Service

Bind the service to Laravel’s service container in a service provider (e.g., AppServiceProvider):

public function register()
{
    $this->app->singleton(UsernameValidator::class, function ($app) {
        return new UsernameValidator();
    });
}

Step 3: Use the Service in Your Controller

Inject the service and use it within your validation logic:

use App\Services\UsernameValidator;
use Illuminate\Http\Request;
public function store(Request $request, UsernameValidator $validator)
{
    $request->validate([
        'username' => ['required', function ($attribute, $value, $fail) use ($validator) {
            if (!$validator->validate($value)) {
                $fail($attribute.' contains the restricted word "admin".');
            }
        }],
    ]);
}

When to Use: Leverage custom validation services for complex and application-wide validation needs.

By mastering these approaches, you’ll be able to create efficient and maintainable validation logic customized to your application’s requirements.

Want to secure your Laravel website with robust validation?

Best Practices for Validation in Laravel

Validation is a cornerstone of any web application, ensuring that the data entering your system is accurate and secure. Laravel offers multiple ways to handle validation, and following best practices will help you maintain a clean, efficient, and scalable codebase. This section outlines key strategies for mastering validation in Laravel.

Validation in Controllers

When working with smaller applications or handling straightforward validation logic, performing validation directly in controllers can be effective. However, for more complex applications, this approach can clutter your controller methods. Here is the code to create controller:

public function store(Request $request)
{
    $validated = $request->validate([
        'title' => 'required|max:255',
        'content' => 'required',
    ]);
    // Proceed with storing validated data
}

Form Request Validation

Form Request validation is the most recommended approach in Laravel for managing complex or reusable validation rules. It moves validation logic out of the controller, keeping your controllers clean and focused on their primary responsibilities. Run the following Artisan command to create a new form request:

php artisan make:request StorePostRequest

The generated request class resides in the App\Http\Requests directory. Define your validation rules in the rules method:

public function rules()
{
    return [
        'title' => 'required|max:255',
        'content' => 'required',
    ];
}

With the validation logic encapsulated, your Laravel controller method becomes cleaner. Here is the code:

public function store(StorePostRequest $request)
{
    // Validation is automatically handled
    Post::create($request->validated());
}

API Validation

When building APIs, you’ll often need validation tailored for JSON responses instead of HTML forms. Laravel makes it easy to handle validation errors gracefully in APIs. Here is the code of API validation in a controller:

public function store(Request $request)
{
    $request->validate([
        'email' => 'required|email',
    ]);
    // The validated data is available in $request->validated()
}

You can customize how validation errors are returned by modifying the App\Exceptions\Handler class:

public function render($request, Exception $exception)
{
    if ($exception instanceof ValidationException) {
        return response()->json([
            'errors' => $exception->errors(),
        ], 422);
    }
    return parent::render($request, $exception);
}

Error Messages & Translations

Laravel’s robust localization support allows you to customize error messages to suit your application’s needs or translate them for multilingual support. To customize specific error messages, edit the language file located at resources/lang/en/validation.php. For instance:

'custom' => [
    'email' => [
        'required' => 'We need your email address!',
    ],
],

If the email field is missing, Laravel will display the custom message: “We need your email address!”.

By adhering to these best practices, you’ll ensure your application’s validation logic is efficient, scalable, and easy to maintain. If you are looking to build a secured website with robust validation, get in touch with our Laravel development company.

Testing Custom Validation Rules in Laravel

Testing your custom validation rules is essential to ensure they function correctly and maintain the reliability of your application. Laravel provides robust tools for unit testing, making it easy to verify that your custom rules behave as expected under various conditions. Here is the example of testing a custom rule:

public function testUppercaseRule()
{
    $rule = new Uppercase;
    $this->assertTrue($rule->passes('username', 'UPPERCASE'));
    $this->assertFalse($rule->passes('username', 'lowercase'));
}

Testing custom validation rules in Laravel is essential to ensure their accuracy and reliability across various scenarios. By using Laravel’s robust testing tools and following best practices, you can maintain high-quality validation logic and boost your user experience.

Need to take your Laravel Application to the next level?

FAQs on Creating and Applying Validation Rules in Laravel

Can I customize the error messages for validation rules in Laravel?
Yes, you can customize the error messages for validation rules in Laravel. You can do this by passing an array of custom messages as the third parameter to the validate method. You can also use the messages method on the Validator facade to set custom error messages for specific fields.
What are some common validation rules in Laravel?
Some common validation rules in Laravel include required for making a field mandatory, email for validating email addresses, numeric for accepting only numbers, and min and max for specifying minimum and maximum lengths for a field.
How can I test my validation rules in Laravel?
Laravel provides a built-in Validator class for testing your validation rules. You can use the passes method to check if the input data passes all the rules, and the fails method to check if any of the rules fail. You can also use the Validator facade in your unit tests to test validation rules.

Wrapping Up

Mastering validation in Laravel is key to building secure and reliable applications. By understanding the built-in validation rules, you can handle most common validation needs with ease. However, as your application grows, custom validation rules become essential for handling unique requirements.

Implementing best practices like using form requests or API validation ensures your code remains clean and maintainable. Testing your custom validation rules helps you catch issues early, ensuring that everything works as expected. With these tools and techniques, you can handle user input, protect your application, and create a smoother experience for your users.If you are looking to build a website with enhanced security and performance, hire Laravel developers.

author
Mayur Upadhyay is a tech professional with expertise in Shopify, WordPress, Drupal, Frameworks, jQuery, and more. With a proven track record in web development and eCommerce development.

Leave a comment