framework-web 26.8.151

lingting framework
Documentation

framework-web

Web 层运行时核心:请求与响应模型、请求上下文、错误分类与日志、参数提取 trait、授权规则与路由模型。 框架无关,HTTP 服务器实现见 framework-web-axum。

feature

feature 作用
collect(默认关闭) 启用基于 inventory 的路由收集,提供 web_api_iter,并传递开启 framework-proc-web/collect

请求

WebRequest 为服务器适配层填充的请求快照:

字段 说明
method WebMethod
scheme、authority 协议与主机
path 请求路径,匹配时忽略两端 /
headers 请求头,MultiStringValue
query 查询参数,MultiStringValue
body 原始请求体 Bytes
client_ip 客户端地址,可选
trace_id 链路标识:优先取 x-trace-id 请求头,缺失时由服务器生成雪花 ID
receive_time 服务器收到请求的时刻,毫秒时间戳

WebMethod 包含 Get、Post、Put、Patch、Delete、Options 与 Other(String)。 WebMethod::from_name 会转大写后匹配,未识别的方法落入 Other。

上下文

WebContext 持有 Arc<WebRequest>,并缓存解析后的 JSON:

  • request()、request_arc()、query()、body():直接访问原始数据。
  • body_json():解析请求体 JSON 并缓存,失败返回参数错误。
  • query_json():把查询参数转为 JSON 对象,单值转字符串、多值转数组,并缓存。

上下文通过 Tokio task-local 传递:

use framework_web::{scope_web, use_web};

scope_web(context, async {
    let context = use_web()?;      // 在作用域内可获取
    let json = context.body_json()?;
    # Ok::<(), anyhow::Error>(())
}).await;

不在作用域内时 use_web() 返回错误。

参数提取

FromWeb 是参数提取 trait,由 framework-proc-web 生成的代码调用。

类型 行为
Json<T> GET 请求从查询参数提取,其他方法从请求体提取
Query<T> 始终从查询参数提取
PaginationParams 从查询参数或请求体提取,并做分页校验

分页校验规则:current 小于等于 0 时取 1,size 小于等于 0 时取 10,超过 100 时报错, 排序字段必须由字母、数字或下划线组成且以字母或下划线开头,否则报错。

响应

WebResponse 由 status、headers、body 组成,body 为 WebBody:

  • WebBody::Bytes(Bytes):一次性返回,String、Vec<u8>、Bytes 均可 From 转换。
  • WebBody::Stream(BoxStream<'static, Result<Bytes, std::io::Error>>):流式返回,用于 SSE 等场景, 通过 is_stream() 判断。

构造方法:

方法 说明
empty() 204 空响应
from_t(value, request) 包装为 R::ok(value),JSON 响应
from_r(r, request) 序列化 R<T>
from_result_t / from_result_r 从 Result 转换,错误转为错误响应
from_result(response, request) 从 Result<WebResponse> 转换
from_error(error, request) 错误响应,同时记录日志
from_error_request(error, trace_id, method, path) 无 WebRequest 时记录日志
stream(status, content_type, stream) 流式响应

JSON 响应会设置 content-type: application/json; charset=utf-8 与 content-length。 序列化失败会转为返回值转换错误。

错误

WebError 按 WebErrorKind 分类,状态码复用 framework-core 的 RCodeKind:

类型 状态码 对外消息
Message 500 原消息
Parameter 400 原消息
Unauthorized 401 原消息
Forbidden 403 原消息
NotFound 404 原消息
ReturnConversion 500 服务器内部错误
Internal 500 服务器内部错误
Panic 500 服务器内部错误

构造方法:message、parameter、return_conversion、not_found、unauthorized、forbidden、 internal、panic、with_source。带 source 的构造方法在 debug 构建下会记录源码位置。

log / log_request 输出包含分类、状态码、trace_id、方法、路径、源码位置、 错误链与 backtrace 的 error! 日志。source_backtrace 取 anyhow 的 backtrace。

WebErrorExt 为 Result<T, E> 提供快捷转换:message()、parameter(msg)、internal(msg)。

WebResponse::from_error 接受 anyhow::Error,内部会向下转型:WebError 直接使用, &'static str 与 String 归为 Message,其他归为 Internal。

授权

AuthRule 描述接口的访问要求,序列化字段名为 camelCase:

字段 语义
anonymous Some(true) 时跳过全部校验
organizations / organizations_any 全部满足 / 任一满足
permissions / permissions_any 同上
roles / roles_any 同上
rules 子规则,需全部满足
rules_any 子规则,需任一满足

AuthRule::login() 为默认值(anonymous = false),AuthRule::anonymous() 允许匿名。 check(organizations, permissions, roles) 汇总校验;未提供某类值而规则要求该类时校验失败, 提供了空列表且规则有要求时同样失败。

授权规则的执行由服务器适配层决定,见 framework-web-axum 的路由包装器。

路由

WebRoute 由 method、path、auth、invoke 组成,invoke 为 Arc<dyn Fn() -> BoxFuture<'static, WebResponse> + Send + Sync>。

开启 collect 后:

  • WebApiBuilder(pub fn() -> WebRoute) 作为 inventory 注册项。
  • push_web_api!(builder) 宏用于提交注册。
  • web_api_iter() 返回所有已注册路由。

catch_panic 把异步任务的 panic 转为 WebError::Panic 错误,宏生成的代码在调用函数体前会包裹它。