Validation

Validate incoming request data with a fluent, Laravel-style syntax. Rules are defined as pipe-separated strings and errors are automatically collected per field.

Basic usage
@POST(value = "/register", name = "register.store")
private Object store(Request req, Response res) {
    Map<String, Object> data = RequestValidator.validate(req, Map.of(
        "username", "required|min:3|max:20|alphanumeric",
        "email",    "required|email|unique:users,email",
        "password", "required|min:8|confirmed"
    ));

    // data contains only validated fields
    return render("dashboard.html", Map.of());
}
Safe validation — handle errors manually

Use validateSafe() to get a ValidationResult instead of catching an exception.

@POST(value = "/register", name = "register.store")
private Object store(Request req, Response res) {
    ValidationResult result = RequestValidator.validateSafe(req, Map.of(
        "username", "required|min:3|max:20",
        "email",    "required|email",
        "password", "required|min:8"
    ));

    if (result.fails()) {
        return render("register.html", Map.of(
            "errors", result.getErrors(),
            "old",    req.queryMap().toMap()
        ));
    }

    Map<String, Object> data = result.getData();
    // ...
}
Available rules
Rule Description
requiredField must not be null or empty
emailMust be a valid email address
min:8Minimum 8 characters
max:255Maximum 255 characters
between:3,20Length or value between 3 and 20
numericMust be a number
integerMust be an integer
alphaLetters only
alphanumericLetters and numbers only
urlMust be a valid URL
confirmedMust match field_confirmation
unique:users,emailMust not exist in table/column
in:admin,editor,userMust be one of the listed values
regex:^[A-Z]+$Must match the given pattern
Displaying errors in templates

The error() and old() helpers are available in all Pebble templates when you pass errors and old to the view.

<form method="POST" action="/register">
    {{ csrf_field() | raw }}

    <input
        type="text"
        name="username"
        value="{{ old('username') }}"
    >
    {% if error('username') %}
        <span class="error">{{ error('username') }}</span>
    {% endif %}

    <input
        type="email"
        name="email"
        value="{{ old('email') }}"
    >
    {% if error('email') %}
        <span class="error">{{ error('email') }}</span>
    {% endif %}

    <button type="submit">Register</button>
</form>
Validation in LiveComponents

Use LiveComponentValidator to validate component state directly, without an HTTP request.

@LiveComponentImpl
public class RegisterForm extends LiveComponent
{
    @State
    private String username = "";

    @State
    private String email = "";

    public void submit() {
        ValidationResult result = LiveComponentValidator.validate(
            Map.of("username", username, "email", email),
            Map.of(
                "username", "required|min:3|alphanumeric",
                "email",    "required|email"
            )
        );

        if (result.fails()) {
            // Handle errors
            return;
        }

        // Process validated data
    }

    @Override
    public String template() {
        return "components/register-form.html";
    }
}
💡 Behavior
  • • Rules are evaluated in order — validation stops at the first failure per field
  • • Only validated fields are returned in the data map
  • validate() throws a ValidationException on failure
  • validateSafe() returns a ValidationResult without throwing
  • unique: checks against your ActiveJDBC models automatically