Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Validation

This document explains how to define and implement validation for fields in Biyard Rust projects using the api_model macro in combination with the validator crate.

Overview

Field validation ensures data integrity by verifying that data meets certain criteria before being processed or stored. Validation attributes defined using the validator crate automatically integrate with generated models.

Defining Validation

Validation is defined directly within the data model structs using attributes provided by the validator.

Example

Here's a practical example demonstrating field validation on a User model:

#![allow(unused)]
fn main() {
use bdk::prelude::*;
use validator::Validate;

#[derive(Validate)]
#[api_model(base = "/v1/", table = users)]
pub struct User {
    #[api_model(primary_key)]
    pub id: i64,

    #[validate(custom(function = "validate_nickname"))]
    pub nickname: String,

    #[validate(email)]
    pub email: String,

    #[validate(url)]
    pub profile_url: String,
}
}

Supported Validation Attributes

Use validation attributes provided by the validator crate:

Validator TypeDescriptionExample
emailValidates that a field is a valid email#[validate(email)]
urlValidates that a field is a valid URL#[validate(url)]
lengthValidates field length#[validate(length(min = 1, max = 20))]
rangeValidates numeric ranges#[validate(range(min = 1, max = 100))]
customValidates using a custom function#[validate(custom(function="validate_nickname"))]

Custom Validation Example

Custom validation allows you to write specific validation logic:

#![allow(unused)]
fn main() {
use validator::ValidationError;

fn validate_nickname(nickname: &str) -> Result<(), ValidationError> {
    if nickname.len() < 3 {
        return Err(ValidationError::new("nickname too short"));
    }
    Ok(())
}
}

Automatic Inclusion in Generated Models

When defining validations with validator, generated request and response structures automatically include validation checks:

#![allow(unused)]
fn main() {
#[tokio::main]
async fn signup_user(user: User) -> Result<()> {
    user.validate()?;
    // Proceed if validation succeeds
    Ok(())
}
}

Recommendations and Best Practices

  • Define clear and concise validation rules.
  • Always use specific validators rather than overly generic ones for clearer error messages.
  • Leverage custom validations for complex validation logic.

Following these guidelines ensures robust and maintainable data validation in your Biyard Rust projects.