framework-web-axum
基于 axum 的 HTTP 服务器适配层:请求分发、路由收集、CORS 处理与服务启动。 请求/响应模型与错误处理由 framework-web 提供。
feature
| feature | 作用 |
|---|---|
collect(默认开启) |
传递开启 framework-web/collect,使 web_api 宏生成的路由被自动收集 |
启动服务
use axum_builder;
let server = axum_builder.bind.await?;
server.run.await?;
# Ok::
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 WebRouteWrapper;
use Arc;
let wrapper: WebRouteWrapper = new;
未提供 wrapper 时使用默认实现,直接执行 route.invoke()。
WebRouter::invoke(web_context, axum_context) 会依次注入 AxumContext 与 WebContext
两层 task-local 作用域,再查找并执行路由。
分发流程
dispatch 作为 axum 的 fallback 处理所有请求:
- 读取
x-trace-id请求头,为空时用next_id()生成雪花 ID。 - 收集请求头(键名转小写)与查询参数(保留原大小写),读取请求体,上限 16 MiB。
- 组装
WebRequest:scheme缺失时取http,authority缺失时取host请求头,client_ip取连接对端 IP。 OPTIONS请求直接返回WebResponse::empty()(204),不进入路由查找。- 其他请求在
catch_panic中执行WebRouter::invoke,panic 与错误都转为错误响应。 - 应用 CORS 响应头,写入
x-trace-id,转换为 axumResponse。
响应体支持一次性 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 ;
let context = use_axum?;
let address = context.address; // 形如 127.0.0.1:8080
# Ok::
scope_axum(context, future) 建立作用域,use_axum() 在作用域内获取上下文,否则返回错误。
组装
build_router(wrapper) 创建 WebRouter;build_router_with(router, context, cors)
把路由组装为 axum Router,并挂载统一的 fallback 分发。