Syntax design choose for the multi-protocol web framework
⚓ Rust 📅 2026-01-27 👤 surdeus 👁️ 1I am working on redesign the syntax for hotaru framework (which is a multi-protocol web framework) as I gathered some feedback from the previous discussion.
Seems most of people don't like the idea of putting all endpoints into one custom macro, like the original design:
endpoint! {
APP.url("/new_syntax/<arg>"),
middleware: [..],
config: ["ConfigString"],
/// Example endpoint using new syntax
pub fn new_syntax_endpoint(context: HTTP) {
let args = context.pattern("arg");
text_response(format!("New syntax endpoint called with arg: {}", args.unwrap_or_default()))
}
}
I am thinking about the following 2 alternatives:
#[endpoint]
#[path("/")]
#[middleware([logger_middleware])]
fn index <HTTP>() {
akari_render!(
"home.html",
title = "Hotaru Example",
page_title = "Welcome to Hotaru 0.8",
show_message = true,
message = "Framework successfully running!",
items = [
"Protocol Abstraction Layer",
"Async/await support",
"Middleware system",
"Template rendering"
]
)
}
#[middleware]
fn logger_middleware <HTTP>() {
println!("Request received: {} {}", req.method(), req.path());
next(context).await
}
Or
#[endpoint(path = "/", middleware = [logger_middleware])]
fn index <HTTP>() {
akari_render!(
"home.html",
title = "Hotaru Example",
page_title = "Welcome to Hotaru 0.8",
show_message = true,
message = "Framework successfully running!",
items = [
"Protocol Abstraction Layer",
"Async/await support",
"Middleware system",
"Template rendering"
]
)
}
#[middleware]
fn logger_middleware <HTTP>() {
println!("Request received: {} {}", req.method(), req.path());
next(context).await
}
You may specific the APP we register by adding #[app(APP_NAME)] or app=... for both syntax. The APP instance is not specified, in default we will register into the one named as APP as per the convention.
I want to see the community's opinion. Whether those 2 are good enough? And which one we prefer more.
Also, I found a problem with the proc macro (which I am aware when I was designing the old syntax) is that normal proc macro attribute only accepts normal rust syntax. Which means the following is not accepted:
#[middleware]
fn logger_middleware <HTTP>(req) {
println!("Request received: {} {}", req.method(), req.path());
next(context).await
}
Then if we want to give some other names for the req we must do the following:
#[middleware]
fn logger_middleware <HTTP>(req_name: DummyType) {
println!("Request received: {} {}", req_name.method(), req_name.path());
next(context).await
}
I am thinking how to deal with this or we just simply ban custom naming for the request variable?
Previous discussion: We built a Rust web framework around one idea: everything about an endpoint belongs together. Feedback wanted
Repo: GitHub - Field-of-Dreams-Studio/hotaru: Small, sweet, easy framework for full-stack Rust web applications supporing multiple & user-defined protocol (Please refer to 0.8-Phase 1 branch instead of master branch)
1 post - 1 participant
🏷️ Rust_feed