ironic 1.0.7

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

Ironic

CI Release Crates.io Docs.rs License Rust Discord Sponsor

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

We welcome contributions! Here's how to get started.

First Time

  1. Find an issue tagged good first issue or help wanted
  2. Comment on the issue that you're working on it
  3. Follow the steps below to open a PR

Setup

git clone https://github.com/ironic-org/ironic.git
cd ironic
cargo build
cargo test

Branch Naming

feat/description     # new features
fix/description      # bug fixes
chore/description    # tooling, CI, deps
docs/description     # documentation
refactor/description # code restructuring

Commit Messages

Follow Conventional Commits:

feat: add #[ironic::test] proc-macro
fix: resolve DI cycle detection panic
chore: bump axum to 0.8.10
docs: update release workflow guide

PR Workflow

  1. Create a branch from main: git checkout -b feat/my-feature
  2. Make your changes
  3. Run checks locally:
    cargo build
    cargo test --all-features
    cargo clippy --workspace --all-targets --all-features -- -D warnings
    cargo fmt --all -- --check
    
  4. Commit and push: git push origin feat/my-feature
  5. Open a PR against main with:
    • Clear title matching commit conventions
    • Description explaining what and why
    • Closes #N to link the issue
  6. Ensure CI passes on your PR
  7. Address reviewer feedback with additional commits

CI Pipeline

Check Description
Formatting cargo fmt --check
Clippy cargo clippy -D warnings (all features)
Test cargo test --all-features (stable + nightly)
Audit cargo audit (vulnerability scan)
Deny cargo deny (license + duplicate check)
Docs Build docs site
Fuzz 60s smoke test on nightly

Code Style (Enforced — PRs Must Comply)

PRs that violate these rules will not be merged:

  • Patterns — follow existing conventions in the codebase
  • No comments — code should be self-documenting. Comments only for non-obvious logic
  • Small functions — each function should have a single responsibility
  • Document all public APIs — every public type, method, and module export needs a doc comment
  • Tests required — new features must include tests; bug fixes must include a regression test

All items are checked via the PR template checklist. CI enforces what it can (fmt, clippy, tests); the rest is enforced during review.

Need Help?

Support

If Ironic helps you build something awesome, consider sponsoring the project. Your support covers hosting, tooling, and development time.

License

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