anycms-core
支持多种 Rust Web 框架的统一 API 响应库。
特性
- 框架无关的核心:
ApiResult<T>结构独立于任何 Web 框架工作 - 多框架支持:内置 actix-web 和 axum 集成
- Feature flags:按需使用 - 零未使用的依赖
- 灵活的响应格式:支持单值、列表、分页、错误码和额外元数据
- 字段级验证错误:
FieldError支持表单验证场景 - 业务错误码:
bizCode独立于 HTTP 状态码,支持自定义业务语义 - 响应时间戳:内置
timestamp字段,支持自动注入当前时间 - 请求追踪:内置
traceId字段,方便生产环境排查 - 序列化风格可配置:支持 camelCase(默认)和 snake_case
- tracing 集成:自动按响应级别记录日志(4xx -> WARN, 5xx -> ERROR)
安装
在 Cargo.toml 中添加:
[]
= "0.5"
Feature Flags
actix(默认):启用 actix-web 集成axum:启用 axum 集成validator:启用validatorcrate 集成,自动转换验证错误tracing:启用tracingcrate 集成,自动按级别记录错误日志full:启用所有集成(actix + axum + validator + tracing)camel-case(默认):JSON 字段使用 camelCasesnake-case:JSON 字段使用 snake_case
示例
# 默认(actix-web + camelCase)
= "0.5"
# 仅 axum
= { = "0.5", = false, = ["axum"] }
# snake_case 风格
= { = "0.5", = ["snake-case"] }
# 启用 validator 集成
= { = "0.5", = ["validator"] }
# 启用 tracing 集成
= { = "0.5", = ["tracing"] }
# 启用全部
= { = "0.5", = ["full"] }
项目结构
src/
├── lib.rs # 库入口,带 feature 条件导出
├── result.rs # 核心 ApiResult<T>、错误类型、FieldError
├── pagination.rs # 分页元数据结构
├── tracing.rs # tracing 集成 (feature = "tracing")
├── validator.rs # validator crate 集成 (feature = "validator")
└── frameworks/
├── mod.rs # 框架模块声明
├── actix.rs # actix-web 集成 (Responder trait + 中间件)
└── axum.rs # axum 集成 (IntoResponse trait + 中间件)
架构设计
该库采用清晰的关注点分离设计:
-
核心层 (result.rs, pagination.rs)
- 包含数据结构和构建器方法
- 零框架依赖
- 无论启用哪个 feature 都会编译
-
框架层 (frameworks/)
- 实现框架特定的 trait
- 基于 feature flags 条件编译
- 相互隔离,避免冲突
-
集成层 (tracing.rs, validator.rs)
- 可选的第三方 crate 集成
- 通过 feature flags 按需启用
使用方法
成功响应
use ;
// 单值
let result = value;
// 列表 + 分页
let result = list
.with_pagination
.with_extra;
// 空响应
let result = ok;
错误响应
use ;
// 使用 ApiError
let result: = not_found.into;
// 使用快捷方法
let result = fail.with_code;
业务错误码
bizCode 独立于 HTTP 状态码,用于前端业务逻辑判断:
use ApiResult;
// HTTP 404 + 业务码 10001
let result = fail
.with_code
.with_biz_code;
时间戳
use ApiResult;
// 自动注入当前时间(Unix 毫秒)
let result = value.with_current_timestamp;
// 手动指定时间戳
let result = ok.with_timestamp;
验证错误
use ;
// 一次性传入所有字段错误
let result: = validation_errors;
// 或链式添加
let result = fail
.with_code
.with_error
.with_error;
validator crate 集成
启用 validator feature 后,可以自动将 validator::ValidationErrors 转换为 ApiResult 响应:
use ApiResult;
use Validate;
async
嵌套结构体的字段名会自动加前缀(如 address.city),支持与自定义业务错误合并:
use ;
请求追踪
use ApiResult;
let result = fail
.with_code
.with_trace_id;
分页
use ResultPagination;
let pagination = new;
// 自动计算并输出:
// - total: 95
// - page: 3
// - pageSize: 10
// - totalPages: 10
// - hasNextPage: true
// - hasPrevPage: true
错误码
ErrorCode 覆盖常用 HTTP 状态码,每个变体都有对应的 ApiError 快捷方法:
use ApiError;
bad_request; // 400
unauthorized; // 401
forbidden; // 403
not_found; // 404
conflict; // 409
request_timeout; // 408
payload_too_large; // 413
too_many_requests; // 429
validation; // 422
internal; // 500
gateway_timeout; // 504
框架集成
Actix-web
use get;
use ApiResult;
async
Axum
use Path;
use ApiResult;
async
Tracing 集成
启用 tracing feature 后,可以通过 with_tracing() 方法自动按响应级别记录日志:
[]
= { = "0.5", = ["tracing"] }
使用方法
use ;
// 成功响应:不产生任何日志(避免噪音)
let result = value.with_tracing;
// 4xx 错误:WARN 级别
let result = fail
.with_code
.with_tracing; // -> tracing::warn!
// 5xx 错误:ERROR 级别
let result = fail
.with_code
.with_tracing; // -> tracing::error!
日志级别规则
| 响应状态 | code 范围 | 日志级别 | 说明 |
|---|---|---|---|
成功 (success: true) |
- | 无日志 | 避免噪音 |
| 客户端错误 | 400-499 | WARN |
如参数错误、权限不足 |
| 服务端错误 | 500+ | ERROR |
如内部异常、网关超时 |
日志会自动包含 code、trace_id、biz_code 等结构化字段。
请求追踪中间件
anycms-core 为 actix-web 和 axum 提供了中间件,自动为响应注入 traceId。
工作原理
- 从请求头中提取 trace ID(默认检查
X-Request-ID和X-Trace-ID) - 若请求头中不存在,则自动生成 UUID v4
- 将 trace ID 注入到
ApiResult响应的traceId字段
Actix-web 使用
use ;
use ApiResultLayer;
new
Axum 使用
use ;
use api_result_middleware;
// 零配置(使用默认配置)
let app = new
.route
.layer;
// 自定义配置
use ;
let config = ApiResultMiddlewareConfig ;
let app = new
.route
.layer;
ResultPagination 数据库查询辅助
ResultPagination 提供了数据库分页查询的辅助方法,可以直接用于 SQL OFFSET / LIMIT 子句:
use ResultPagination;
let pagination = new;
// 用于 SQL OFFSET 子句: (page - 1) * page_size
let offset = pagination.offset; // 20
// 用于 SQL LIMIT 子句: 等同于 page_size
let limit = pagination.limit; // 10
// 页面判断
pagination.is_first_page; // false (当前是第 3 页)
pagination.is_last_page; // false (总共 10 页)
// 翻页
pagination.next_page; // Some(4)
pagination.prev_page; // Some(2)
典型数据库查询场景
use ;
async
API 响应格式
成功响应(单值)
成功响应(列表 + 分页)
空成功响应
错误响应
业务错误码响应
验证错误响应
带追踪的错误响应
示例
运行演示示例:
# Actix-web 演示
# Axum 演示
# 验证错误演示
# validator crate 集成演示
# 请求追踪演示
# 业务错误码 + 时间戳演示
# ResponseData From trait 演示
# 中间件演示 (Actix-web)
# 中间件演示 (Axum)
# tracing 集成演示
# 检查所有示例
许可证
MIT