framework-web-axum 26.8.151

lingting framework
Documentation

framework-web-axum

基于 axum 的 HTTP 服务器适配层:请求分发、路由收集、CORS 处理与服务启动。 请求/响应模型与错误处理由 framework-web 提供。

feature

feature 作用
collect(默认开启) 传递开启 framework-web/collect,使 web_api 宏生成的路由被自动收集

启动服务

use framework_web_axum::axum_builder;

let server = axum_builder("127.0.0.1", 8080).bind().await?;
server.run(None).await?;
# Ok::<(), anyhow::Error>(())
  • axum_builder(bind_address, bind_port):bind_port 小于等于 0 或超出 u16 范围时使用随机端口。
  • AxumBuilder::with_cors(f):设置 CORS 解析函数,默认拒绝跨域。
  • AxumBuilder::bind():绑定端口,返回 AxumServer;端口为 0 时由系统分配。
  • AxumServer::context():返回 AxumContext,其中 port 是实际绑定端口。
  • AxumServer::router():服务启动后可取到 Arc<WebRouter>,未启动时为 None。
  • AxumServer::run(wrapper):启动并持续运行;重复调用返回错误。

路由

WebRouter::new(wrapper) 在构造时通过 framework_web::web_api_iter() 收集所有已注册路由, 按 WebMethod 与 path 建索引。查找时忽略请求路径两端的 /,匹配不到返回 404。

WebRouteWrapper 用于在命中路由后包裹执行,可用于授权校验、上下文注入等:

use framework_web_axum::WebRouteWrapper;
use std::sync::Arc;

let wrapper: WebRouteWrapper = Arc::new(|route| {
    Box::pin(async move { Ok(route.invoke().await) })
});

未提供 wrapper 时使用默认实现,直接执行 route.invoke()。

WebRouter::invoke(web_context, axum_context) 会依次注入 AxumContext 与 WebContext 两层 task-local 作用域,再查找并执行路由。

分发流程

dispatch 作为 axum 的 fallback 处理所有请求:

  1. 读取 x-trace-id 请求头,为空时用 next_id() 生成雪花 ID。
  2. 收集请求头(键名转小写)与查询参数(保留原大小写),读取请求体,上限 16 MiB。
  3. 组装 WebRequest:scheme 缺失时取 http,authority 缺失时取 host 请求头, client_ip 取连接对端 IP。
  4. OPTIONS 请求直接返回 WebResponse::empty()(204),不进入路由查找。
  5. 其他请求在 catch_panic 中执行 WebRouter::invoke,panic 与错误都转为错误响应。
  6. 应用 CORS 响应头,写入 x-trace-id,转换为 axum Response。

响应体支持一次性 Bytes 与流式 BoxStream,分别映射为 Body::from 与 Body::from_stream。

分发阶段自身出错(如请求体读取失败)时,会转换为错误响应;若连响应构造都失败, 返回 500 空响应并记录日志。

CORS

AxumCors 是响应头的简短映射,None 表示不输出该响应头:

字段 响应头
origin access-control-allow-origin
methods access-control-allow-methods
headers access-control-allow-headers
expose access-control-expose-headers
credentials access-control-allow-credentials
max_age access-control-max-age

AxumCors::fixed() 返回不输出任何 CORS 头的静态实例,即拒绝跨域,也是默认行为。 AxumCors::apply(&mut headers) 把配置写入响应头。

with_cors 接收 Fn(&WebContext) -> AxumCors,可按请求动态决定 CORS 配置。

上下文

AxumContext 记录绑定地址与实际端口:

use framework_web_axum::{scope_axum, use_axum};

let context = use_axum()?;
let address = context.address();   // 形如 127.0.0.1:8080
# Ok::<(), anyhow::Error>(())

scope_axum(context, future) 建立作用域,use_axum() 在作用域内获取上下文,否则返回错误。

组装

build_router(wrapper) 创建 WebRouter;build_router_with(router, context, cors) 把路由组装为 axum Router,并挂载统一的 fallback 分发。