Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use routes attributes macros for multiple methods in Actix-Web

In the Actix Web Framework, how does one use the route attributes macros (#[http_method("route")]) to bind multiple http methods to one function?

For example, I have this trivial endpoint:

/// Returns a UUID4.
#[get("/uuid")]
async fn uuid_v4() -> impl Responder {
    HttpResponse::Ok().json(Uuid {
        uuid: uuid::Uuid::new_v4(),
    })
}

I would like to have the same endpoint handle HEAD requests, how do I do this? My initial approach was to just stack up the macros:

/// Returns a UUID4.
#[get("/uuid")]
#[head("/uuid")]
async fn uuid_v4() -> impl Responder {
    HttpResponse::Ok().json(Uuid {
        uuid: uuid::Uuid::new_v4(),
    })
}

But I do get a compilation error:

    |
249 | async fn uuid_v4() -> impl Responder {
    |          ^^^^^^^ the trait `actix_web::handler::Factory<_, _, _>` is not implemented for `<uuid_v4 as actix_web::service::HttpServiceFactory>::register::uuid_v4`

I have gone through the actix-web and actix-web-codegen docs and didn't find anything addressing this

like image 869
mattgathu Avatar asked Feb 19 '20 21:02

mattgathu


2 Answers

you can do

#[route("/", method="GET", method="POST", method="PUT")]
async fn index() -> impl Responder {
  HttpResponse::Ok().body("Hello world!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
  HttpServer::new(move || {
    App::new()
        .service(index)
  })
  .bind("127.0.0.1:8080")?
  .run()
  .await
}
like image 138
tbounsiar Avatar answered Nov 12 '22 18:11

tbounsiar


An example with multiple path and multiple methods for one resource

async fn index() -> impl Responder {
  HttpResponse::Ok().body("Hello world!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
  HttpServer::new(move || {
    App::new()
        .service(
            actix_web::web::resource(vec!["/", "/index"])
                .route(actix_web::web::get().to(index))
                .route(actix_web::web::post().to(index))
            )
  })
  .bind("127.0.0.1:8080")?
  .run()
  .await
}
like image 6
Jbs Nice Avatar answered Nov 12 '22 17:11

Jbs Nice