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 ;
scope_web.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 错误,宏生成的代码在调用函数体前会包裹它。