14 releases

new 0.3.1 Jul 8, 2025
0.3.0 Jul 4, 2025
0.2.9 Jul 3, 2025
0.2.3 Feb 27, 2025
0.1.1 Dec 16, 2024

#85 in HTTP client

Download history 1/week @ 2025-03-18 8/week @ 2025-04-15 1/week @ 2025-04-22 3/week @ 2025-05-06 6/week @ 2025-05-13 1/week @ 2025-06-17 938/week @ 2025-07-01

939 downloads per month

MIT license

130KB
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.1" }

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.1", 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–24MB
~366K SLoC