salvo-rs / salvo

A powerful web framework built with a simplified design.
https://salvo.rs
Apache License 2.0
3.4k stars 208 forks source link

Feature: Consider supporting handler macro for structures' methods #818

Closed wildonion closed 4 months ago

wildonion commented 4 months ago

I hope you guys are doing well, thanks for this great fremework, the routing system is a great feature simplifies handling api logics a lot, however I have couple of ideas in the mind want to share with you, wondering if we could implement them in future versions. one of them is writing structure based conrollers, currently as I'm designing the apis there is this pattern of #[handler] that can be added to the impl of structure but there is a lock of supporting of adding it on top of structure methods like if we could implement the following logic or similar to that would be a great option:

struct HelloController;

#[handler]
impl HelloController{

    async fn check_health(req: &mut Request, res: &mut Response){ // GET probably!

    }

    async fn send_hello(req: &mut Request, res: &mut Response){ // POST probably!

    }

    async fn take_back_health(req: &mut Request, res: &mut Response){ // DELETE 

    }
}

or

#[probably_a_controller_registration_macro]
impl HelloController{

    #[handler]
    async fn check_health(req: &mut Request, res: &mut Response){ // GET probably!

    }

    #[handler]
    async fn send_hello(req: &mut Request, res: &mut Response){ // POST probably!

    }

    #[handler]
    async fn take_back_hello(req: &mut Request, res: &mut Response){ // DELETE 

    }
}

and the registeration would be something like passing the structure to a method like register():

let hello_router = Router::with_path("/v1/hello/").register(HelloController);
let user_router = Router::with_path("/v1/user/").register(UserController);
let apis = Router::with_path("/api").push(hello_router).push(user_router);

actually this pattern helps a lot in designing api and adds more flexibility to the current router system, in fact

chrislearn commented 4 months ago

Although there are concepts similar to Controller in many web frameworks, I don't think it's necessary to introduce such a concept.

wildonion commented 4 months ago

@chrislearn thanks for your response, yes you're right although there are solutions to forementioned problems like if we could add a custom attribute like #[handler(path="/user/get/<id>/")] and extend the method name in macro handler, the inconsistency problem can be solved or for the middleware issue, a proc macro like #[hoop] or #[middleware] can be used for that then when we're registering the controller the parser will separate each of them to push them into the main router to build the router tree, but as you've mentioned indeed more complex logics behind the framework needs to get handled.

chrislearn commented 4 months ago

As mentioned above, the fact that you want to create multiple complex macros requires a learning cost and no flexibility, but, what benefits do you get? Nothing.