Security / Request Validation

Forms

Never trust user input. Archery provides a deeply integrated, elegant validation system allowing you to declare succinct validation rules directly on the HttpRequest object.

Validating Fields

You can use the request.validate() extension method to validate incoming data against an array of rules.

If the validation fails, Archery automatically logs the error messages into the session (thisSession?.errors) and flashes the old input data so you can repopulate the form for the user. It evaluates to a bool so you can immediately redirect on failure:

router.post('/register', (request) async {
  
  // 1. Validate the email
  final isEmailValid = await request.validate(
    field: 'email', 
    rules: [Rule.required, Rule.email, Rule.unique<User>(column: 'email')]
  );

  // 2. Validate the password
  final isPasswordValid = await request.validate(
    field: 'password', 
    rules: [Rule.required, Rule.min(8)]
  );

  // 3. Immediately bounce back if anything failed
  if (!isEmailValid || !isPasswordValid) {
    return request.redirectBack();
  }

  // Create the user...
});

Validating Entire Schemas

If you prefer to validate the entire payload atomically, you can declare an array of maps using validateAll. It returns true only if every rule in the entire schema passes.

final isValid = await request.validateAll([
  {
    'name': [Rule.required, Rule.max(100)],
  },
  {
    'email': [Rule.required, Rule.email, Rule.unique<User>(column: 'email')],
  },
  {
    'password': [Rule.required, Rule.min(8)],
  }
]);

if (!isValid) {
  return request.redirectBack();
}

Available Rules

The Rule enum exposes the following built-in validation options:

  • Rule.required: The field must be present and not empty.
  • Rule.email: The field must be formatted as a valid email address.
  • Rule.min(int limit): The field length must be greater than or equal to limit.
  • Rule.max(int limit): The field length must be less than or equal to limit.
  • Rule.unique<T>(column: 'name'): The field value must not already exist in the database for the given model T within the specified column.