Hidden Methods Intermediate Since Laravel 10.x

FormRequest::after()

Run additional validation logic after your rules pass — perfect for complex, cross-field checks that don't fit neatly into a single rule.

Overview

The after() method on a Form Request lets you define additional validation callbacks that run after the standard rules have passed. This is ideal for business-logic validation that depends on multiple fields or external services.

Usage

Return an array of closures or invokable classes from the after() method. Each receives the Validator instance so you can add errors conditionally:

use App\Http\Requests\CheckoutRequest;
use Illuminate\Validation\Validator;

class CheckoutRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'product_id' => ['required', 'exists:products,id'],
            'quantity' => ['required', 'integer', 'min:1'],
        ];
    }

    public function after(): array
    {
        return [
            function (Validator $validator) {
                $product = Product::find($this->product_id);

                if ($product && $product->stock < $this->quantity) {
                    $validator->errors()->add(
                        'quantity',
                        "Only {$product->stock} items remaining in stock."
                    );
                }
            }
        ];
    }
}

You can also extract validation logic into dedicated invokable classes:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;

public function after(): array
{
    return [
        new ValidateUserStatus,
        new ValidateShippingTime,
    ];
}

Each invokable class receives the Validator instance via its __invoke method.

When to Use

  • Stock or inventory checks that depend on the validated product ID and quantity together
  • Verifying an external API (payment gateway, address verification) after basic input is validated
  • Complex cross-field validation that would be awkward as a custom Rule object
  • Keeping your rules() method clean by separating structural validation from business logic