#spring-boot #config #tokio-boot #axum-boot #rust-boot

derust

Easy way to start your Rust asynchronous application server using Tokio and Axum frameworks

25 releases

new 0.3.12 Dec 21, 2025
0.3.11 Nov 28, 2025
0.3.10 Aug 20, 2025
0.3.4 Jul 27, 2025
0.1.1 Dec 16, 2024

#362 in HTTP server

MIT license

145KB
3.5K SLoC

derust

Easy way to start your Rust asynchronous application server using Tokio and Axum frameworks.

MIT licensed

Basic usage example

# Cargo.toml

[package]
name = "sample"
version = "0.1.0"
edition = "2021"

[dependencies]
derust = { version = "0.3.12" }

tokio = { version = "1.43.0", features = ["full"] }
axum = { version = "0.8.1", default-features = true, features = ["macros", "tokio"] }
serde_json = { version = "1.0.133" }
// main.rs

use axum::extract::State;
use axum::http::StatusCode;
use axum::routing::get;
use axum::Router;
use derust::envx::Environment;
use derust::httpx::json::JsonResponse;
use derust::httpx::{start, AppContext, HttpError, HttpTags};
use derust::tracex;
use serde_json::json;

#[derive(Clone)]
pub struct AppState {
    pub bar: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // automatic log subscribe and add b3 traceparent
    let _guard = tracex::init();
    
    let env = Environment::detect().ok().unwrap_or(Environment::Local);
    
    // any cloneable struct
    let app_state = AppState {
      bar: "bar".to_string(),
    };
    
    let application_name = "sample";
    
    // easy way to get application context things, like your application state struct
    let context = AppContext::new(application_name, env, app_state)?;
    
    let port = 3000;
    let router = Router::new().nest("/foo", Router::new().route("/", get(handler)));
    
    // automatic health-check route
    // automatic route response status code log
    start(port, context, router).await
}

async fn handler(
    State(context): State<AppContext<AppState>>,
    // automatic add tags into log
) -> Result<JsonResponse, HttpError> {
    let customer_id = "1";
    
    // tags to be added into log
    let tags = HttpTags::from([("customer_id", customer_id)]);
    
    // getting your application state from context
    let bar = context.state().bar.clone();
    
    Ok(JsonResponse::new(
      StatusCode::OK,
      json!({ "foo": bar }),
      tags,
    ))
}

Envs

env default description
SERVER_TIMEOUT_IN_MILLIS 10000 Maximum time in milliseconds that the server will try to respond to a request before returning a timeout error (408 Request Timeout)

Tests

Active start_test feature

derust = { version = "0.3.12", features = ["start_test"] }

And then:

let env = Environment::detect().ok().unwrap_or(Environment::Local);

// any cloneable struct
let app_state = AppState {
    bar: "bar".to_string(),
};

let application_name = "sample";

// easy way to get application context things, like your application state struct
let context = AppContext::new(application_name, env, app_state)?;

let router = Router::new().nest("/foo", Router::new().route("/", get(handler)));

let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();

start_test(context, router, listener).await

Features

License

This project is licensed under the MIT license.

Dependencies

~0–30MB
~380K SLoC