ironic 0.1.9

A batteries-included, type-safe application framework for Rust
Documentation

Ironic

CI Crates.io Docs.rs License Rust Discord

A batteries-included, type-safe application framework for building structured Rust APIs on top of Axum. Inspired by NestJS's modular architecture, grounded in Rust's type system.

Quick Start

cargo install ironic
ironic new my-api
cd my-api
ironic start

Features

  • Modular architecture — modules, imports, exports, provider visibility
  • Dependency injection — singletons, transients, factories, cycle detection
  • HTTP routing — Axum adapter, controllers, parameter extraction
  • API versioning — URI prefix, header-based, and media-type versioning strategies
  • Request pipeline — middleware, guards, interceptors, error handling
  • Parameter pipes — type parsing, validation, and transformation pipelines
  • Validation pipesValidationPipe with garde integration (#[garde(...)] attributes)
  • Exception filters — structured error handling with route-level and global filter chains
  • Response serialization#[derive(Serializable)] with #[exclude] and #[expose(role)] for field-level JSON control
  • Security middleware — CORS, rate limiting, security headers (HSTS, CSP, X-Content-Type-Options, X-Frame-Options), CSRF protection
  • Response compression — gzip, brotli, and zstd via AxumAdapter::compression()
  • Procedural macros#[derive(Injectable)], #[Module], #[controller], #[get], #[post], #[derive(Serializable)]
  • Testing utilities — in-process test app, provider overrides, fluent assertions
  • CLI — project scaffolding, code generators, doctor command
  • OpenAPI — automatic schema generation, Swagger UI
  • Integrations — SQLx, SeaORM, Diesel, MongoDB, Redis, JWT, OAuth, gRPC, GraphQL

Example

use ironic::prelude::*;

#[derive(Injectable)]
#[controller("/users")]
struct UsersController {
    service: Arc<UsersService>,
}

#[routes]
impl UsersController {
    #[get("/:id")]
    async fn find_one(&self, #[param] id: Uuid) -> Json<UserResponse> {
        Json(self.service.find_one(id).await)
    }
}

#[derive(Module)]
#[module(controllers = [UsersController], providers = [UsersService])]
struct UsersModule;

#[ironic::main]
async fn main() {
    FrameworkApplication::builder()
        .module(AppModule::definition())
        .platform(AxumAdapter::new())
        .build()
        .await
        .unwrap()
        .listen("127.0.0.1:3000")
        .await
        .unwrap();
}

Documentation

Contributing

See CONTRIBUTING.md for setup instructions, coding conventions, and PR workflow.

License

Licensed under either of MIT or Apache 2.0 at your option.