25 releases (13 breaking)

Uses new Rust 2024

new 0.84.2 Oct 19, 2025
0.83.0 Aug 27, 2025
0.81.0 Jul 19, 2025
0.77.1 Mar 21, 2025
0.74.2 Nov 11, 2024

#476 in #web-framework

Download history 24060/week @ 2025-06-29 28681/week @ 2025-07-06 33394/week @ 2025-07-13 14028/week @ 2025-07-20 22128/week @ 2025-07-27 28485/week @ 2025-08-03 36813/week @ 2025-08-10 29067/week @ 2025-08-17 35467/week @ 2025-08-24 39378/week @ 2025-08-31 21711/week @ 2025-09-07 34506/week @ 2025-09-14 42916/week @ 2025-09-21 27502/week @ 2025-09-28 43206/week @ 2025-10-05 26346/week @ 2025-10-12

140,914 downloads per month
Used in 3 crates (via salvo-craft)

MIT/Apache

20KB
254 lines

Salvo is an extremely simple and powerful Rust web backend framework. Only basic Rust knowledge is required to develop backend services.

salvo-craft-macros

Salvo Handler modular craft macros.

#[craft]

#[craft] is an attribute macro that converts methods in an impl block into Salvo's Handler implementations.

use salvo::oapi::extract::*;
use salvo::prelude::*;
use salvo_craft_macros::craft;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let service = Arc::new(Service::new(1));
    let router = Router::new()
        .push(Router::with_path("add1").get(service.add1()))
        .push(Router::with_path("add2").get(service.add2()))
        .push(Router::with_path("add3").get(Service::add3()));
    let acceptor = TcpListener::new("127.0.0.1:8698").bind().await;
    Server::new(acceptor).serve(router).await;
}

#[derive(Clone)]
pub struct Service {
    state: i64,
}

#[craft]
impl Service {
    fn new(state: i64) -> Self {
        Self { state }
    }
    /// doc line 1
    /// doc line 2
    #[craft(handler)]
    fn add1(&self, left: QueryParam<i64>, right: QueryParam<i64>) -> String {
        (self.state + *left + *right).to_string()
    }
    /// doc line 3
    /// doc line 4
    #[craft(handler)]
    pub(crate) fn add2(self: ::std::sync::Arc<Self>, left: QueryParam<i64>, right: QueryParam<i64>) -> String {
        (self.state + *left + *right).to_string()
    }
    /// doc line 5
    /// doc line 6
    #[craft(handler)]
    pub fn add3(left: QueryParam<i64>, right: QueryParam<i64>) -> String {
        (*left + *right).to_string()
    }
}

Note: #[craft(handler)] can be replaced with #[craft(endpoint(...))] for more configuration options.

NOTE: When using &self as the method receiver, the containing type must implement the Clone trait.

Documentation & Resources

☕ Donate

Salvo is an open source project. If you want to support Salvo, you can ☕ buy me a coffee here.

⚠️ License

Salvo is licensed under either of

Dependencies

~4.5–6MB
~121K SLoC