【问题标题】:How to use routes attributes macros for multiple methods in Actix-Web如何在 Actix-Web 中为多种方法使用路由属性宏
【发布时间】:2020-06-04 03:37:18
【问题描述】:

Actix Web Framework中,如何使用路由属性宏(#[http_method("route")])将多个http方法绑定到一个函数?

例如,我有这个微不足道的端点:

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

我想让相同的端点处理 HEAD 请求,我该怎么做? 我最初的方法是堆叠宏:

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

但我确实收到了编译错误:

    |
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`

我浏览了actix-webactix-web-codegen docs 并没有找到任何解决这个问题的方法

【问题讨论】:

    标签: rust rust-actix actix-web


    【解决方案1】:

    我假设您将 actix-web: 2.0.0actix-rt: 1.0.0 一起使用,并且您将此处理程序传递给 App.service 方法,如下所示

    HttpServer::new(move || {
                App::new()
                    .wrap(middleware::Logger::default())
                    .service(index)
            })
            .bind(("127.0.0.1", self.port))?
            .workers(8)
            .run()
            .await
    

    那么你将需要像这样编写处理程序 ->

    /// Returns a UUID4.
    #[get("/uuid")]
    async fn uuid_v4(req: HttpRequest) -> Result<web::Json<IndexResponse>> {
        let uuid_header = req
            .headers()
            .get("uuid")
            .and_then(|v| v.to_str().ok())
            .unwrap_or_else(|| "some-id");
        //curl -H "uuid: username" localhost:8080
    
        println!("make use of {}", uuid_header);
        Ok(web::Json(Uuid {
            uuid: uuid::Uuid::new_v4(),
        }))
    }
    

    【讨论】:

    • 我不明白它如何支持除了GET 方法之外的其他任何东西。
    【解决方案2】:

    你可以的

    #[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
    }
    

    【讨论】:

      【解决方案3】:

      一个资源的多个路径和多个方法的示例

      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
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-27
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        • 2023-02-24
        • 1970-01-01
        • 2014-04-20
        相关资源
        最近更新 更多