axum-validated-extractors

Crates.ioaxum-validated-extractors
lib.rsaxum-validated-extractors
version0.2.0
created_at2025-06-05 06:51:35.962898+00
updated_at2025-08-20 06:56:41.25108+00
descriptionA collection of validated extractors for Axum that automatically validate the extracted data using the validator crate
homepage
repositoryhttps://github.com/truehazker/axum-validated-extractors
max_upload_size
id1701133
size51,607
Egor Orlov (truehazker)

documentation

https://docs.rs/axum-validated-extractors

README

axum-validated-extractors

Crates.io Documentation License: MIT CI Rust Version Dependency Status

A collection of validated extractors for Axum that automatically validate the extracted data using the validator crate. This library provides type-safe, automatic validation for your Axum web applications, making it easier to handle and validate incoming requests.

Features

  • ValidatedForm: Validates form data (URL-encoded or multipart)
  • ValidatedJson: Validates JSON data
  • ValidatedQuery: Validates query parameters
  • Automatic validation using the validator crate
  • Type-safe error handling

Installation

Install the crate:

cargo add axum-validated-extractors validator

⚠️ validator crate is required for validation schema creation.

Usage

Basic Example

use axum::{
    routing::post,
    Router,
};
use axum_validated_extractors::{ValidatedJson, ValidatedForm, ValidatedQuery};
use serde::Deserialize;
use validator::Validate;

#[derive(Debug, Deserialize, Validate)]
struct CreateUser {
    #[validate(length(min = 3))]
    username: String,
    #[validate(email)]
    email: String,
}

async fn create_user(
    ValidatedJson(user): ValidatedJson<CreateUser>,
) {
    // user is guaranteed to be valid
    println!("Creating user: {:?}", user);
}

let app: Router<()> = Router::new()
    .route("/users", post(create_user));

Form Data

use axum::{
    routing::post,
    Router,
};
use axum_validated_extractors::ValidatedForm;
use serde::Deserialize;
use validator::Validate;

#[derive(Debug, Deserialize, Validate)]
struct LoginForm {
    #[validate(length(min = 3))]
    username: String,
    #[validate(length(min = 8))]
    password: String,
}

async fn login(
    ValidatedForm(form): ValidatedForm<LoginForm>,
) {
    // form is guaranteed to be valid
    println!("Logging in user: {:?}", form);
}

let app: Router<()> = Router::new()
    .route("/login", post(login));

Query Parameters

use axum::{
    routing::get,
    Router,
};
use axum_validated_extractors::ValidatedQuery;
use serde::Deserialize;
use validator::Validate;

#[derive(Debug, Deserialize, Validate)]
struct SearchParams {
    #[validate(length(min = 2))]
    query: String,
    #[validate(range(min = 1, max = 100))]
    page: Option<u32>,
}

async fn search(
    ValidatedQuery(params): ValidatedQuery<SearchParams>,
) {
    // params is guaranteed to be valid
    println!("Searching with params: {:?}", params);
}

let app: Router<()> = Router::new()
    .route("/search", get(search));

Validation Rules

The validation rules are provided by the validator crate. Here are some common validation rules:

#[derive(Debug, Deserialize, Validate)]
struct User {
    #[validate(length(min = 3, max = 20))]
    username: String,

    #[validate(email)]
    email: String,

    #[validate(range(min = 18))]
    age: u32,

    #[validate(url)]
    website: Option<String>,

    #[validate(regex = "^[a-zA-Z0-9_]+$")]
    nickname: String,
}

See the validator documentation for more validation rules.

Error Handling

The extractors return a ValidationError when validation fails. This error can be converted into a response:

use axum::{
    routing::post,
    Router,
    response::IntoResponse,
};
use axum_validated_extractors::{ValidatedJson, ValidationError};
use serde::Deserialize;
use validator::Validate;

#[derive(Debug, Deserialize, Validate)]
struct CreateUser {
    #[validate(length(min = 3))]
    username: String,
    #[validate(email)]
    email: String,
}

async fn create_user(
    ValidatedJson(user): ValidatedJson<CreateUser>,
) -> impl IntoResponse {
    // If validation fails, a 400 Bad Request response is returned
    // with a detailed error message
    user
}

let app: Router<()> = Router::new()
    .route("/users", post(create_user));

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Commit count: 16

cargo fmt