< 返回版块

lithbitren 发表于 2023-01-14 15:09

Tags:actix,warp_fn

就是actix中间件的简化写法wrap_fn,下面是官方范例。

use actix_web::{dev::Service as _, middleware, web, App};
use actix_web::http::header::{CONTENT_TYPE, HeaderValue};

async fn index() -> &'static str {
    "Welcome!"
}

let app = App::new()
    .wrap_fn(|req, srv| {
        let fut = srv.call(req);
        async {
            let mut res = fut.await?;
            res.headers_mut()
                .insert(CONTENT_TYPE, HeaderValue::from_static("text/plain"));
            Ok(res)
        }
    })
    .route("/index.html", web::get().to(index));

actix的中间件实现代码相当冗余,于是盯上了这个API,本来想写成普通函数通过mod引入,但就得精确定义其输入输出类型,结果发现srv参数的类型是&actix_web::app_service::AppRouting,是一个私有类型,根本没法定义。

兜兜转转查了下,发现有个issue讨论过,发起者应该也在论坛里面,wrap_fn &AppRouting should use Arc #2681,官方推荐的是actix_web_lab::middleware::from_fn,倒也不是不行,但一来又引入了新模块,二来其源码展开后就是那种复杂的中间件写法。

是不是这个API目前如果不引入actix_web_lab的基本是没法不写闭包实现的?


Ext Link: https://docs.rs/actix-web/4.2.1/actix_web/struct.App.html#method.wrap_fn

评论区

写评论
作者 lithbitren 2023-01-18 13:45

谢谢!一到这种时候就脑抽,明明是用泛型函数把这个类型打印出来的,咋就没想到直接泛型函数当做中间件函数就好了。

--
👇
fakeshadow: ```rust fn main() { fn func<S, Req>(req: Req, s: &S) -> S::Future where S: actix_web::dev::Service { s.call(req) }

fn app() {
    let _ = actix_web::App::new().wrap_fn(func);
}

}


善用泛型来表达,目标库不需要export所有类型。
另外你引用的issue说的完全是另一个问题。
fakeshadow 2023-01-17 19:04
fn main() {
    fn func<S, Req>(req: Req, s: &S) -> S::Future
    where
        S: actix_web::dev::Service<Req>
    {
        s.call(req)
    }

    fn app() {
        let _ = actix_web::App::new().wrap_fn(func);
    }
}

善用泛型来表达,目标库不需要export所有类型。 另外你引用的issue说的完全是另一个问题。

1 共 2 条评论, 1 页