anycms-core 0.4.1

A unified API response library supporting multiple Rust web frameworks
Documentation

anycms-core

支持多种 Rust Web 框架的统一 API 响应库。

特性

  • 框架无关的核心ApiResult<T> 结构独立于任何 Web 框架工作
  • 多框架支持:内置 actix-web 和 axum 集成
  • Feature flags:按需使用 - 零未使用的依赖
  • 灵活的响应格式:支持单值、列表、分页、错误码和额外元数据
  • 字段级验证错误FieldError 支持表单验证场景
  • 请求追踪:内置 traceId 字段,方便生产环境排查

安装

Cargo.toml 中添加:

[dependencies]
anycms-core = "0.4"

Feature Flags

  • actix (默认):启用 actix-web 集成
  • axum:启用 axum 集成
  • full:启用所有框架集成

示例

# 默认(仅 actix-web)
anycms-core = "0.4"

# 仅 axum
anycms-core = { version = "0.4", features = ["axum"] }

# 两个框架都启用
anycms-core = { version = "0.4", features = ["full"] }

项目结构

src/
├── lib.rs              # 库入口,带 feature 条件导出
├── result.rs           # 核心 ApiResult<T>、错误类型、FieldError
├── pagination.rs       # 分页元数据结构
└── frameworks/
    ├── mod.rs          # 框架模块声明
    ├── actix.rs        # actix-web 集成 (Responder trait)
    └── axum.rs         # axum 集成 (IntoResponse trait)

架构设计

该库采用清晰的关注点分离设计:

  1. 核心层 (result.rs, pagination.rs)

    • 包含数据结构和构建器方法
    • 零框架依赖
    • 无论启用哪个 feature 都会编译
  2. 框架层 (frameworks/)

    • 实现框架特定的 trait
    • 基于 feature flags 条件编译
    • 相互隔离,避免冲突

使用方法

成功响应

use anycms_core::{ApiResult, ResultPagination};

// 单值
let result = ApiResult::value(user);

// 列表 + 分页
let result = ApiResult::list(users)
    .with_pagination(ResultPagination::new(100, 1, 10))
    .with_extra("has_more", serde_json::json!(true));

// 空响应
let result = ApiResult::<()>::ok();

错误响应

use anycms_core::{ApiResult, ApiError};

// 使用 ApiError
let result: ApiResult<User> = ApiError::not_found("用户不存在").into();

// 使用快捷方法
let result = ApiResult::<User>::fail("操作失败").with_code(500);

验证错误

use anycms_core::{ApiResult, FieldError};

// 一次性传入所有字段错误
let result: ApiResult<User> = ApiResult::validation_errors(vec![
    FieldError::new("email", "格式不正确"),
    FieldError::new("name", "不能为空"),
]);

// 或链式添加
let result = ApiResult::<User>::fail("验证失败")
    .with_code(422)
    .with_error("email", "格式不正确")
    .with_error("name", "不能为空");

请求追踪

use anycms_core::ApiResult;

let result = ApiResult::<User>::fail("用户不存在")
    .with_code(404)
    .with_trace_id("req-abc123");

分页辅助方法

use anycms_core::ResultPagination;

let pagination = ResultPagination::new(95, 3, 10);
pagination.total_pages(); // 10
pagination.has_next();    // true
pagination.has_prev();    // true

框架集成

Actix-web

use actix_web::get;
use anycms_core::ApiResult;

#[get("/users/{id}")]
async fn get_user(path: web::Path<u32>) -> ApiResult<User> {
    match find_user(path.into_inner()).await {
        Some(user) => ApiResult::value(user),
        None => ApiResult::<User>::fail("用户不存在").with_code(404),
    }
}

Axum

use axum::extract::Path;
use anycms_core::ApiResult;

async fn get_user(Path(id): Path<u32>) -> ApiResult<User> {
    match find_user(id).await {
        Some(user) => ApiResult::value(user),
        None => ApiResult::<User>::fail("用户不存在").with_code(404),
    }
}

API 响应格式

成功响应(单值)

{
  "success": true,
  "data": { "id": 1, "name": "张三" }
}

成功响应(列表)

{
  "success": true,
  "data": [
    { "id": 1, "name": "张三" },
    { "id": 2, "name": "李四" }
  ],
  "pagination": {
    "total": 100,
    "page": 1,
    "pageSize": 10,
    "currentPage": 1
  }
}

空成功响应

{
  "success": true
}

错误响应

{
  "success": false,
  "message": "用户不存在",
  "code": 404
}

验证错误响应

{
  "success": false,
  "message": "Validation failed",
  "code": 422,
  "errors": [
    { "field": "email", "message": "格式不正确" },
    { "field": "name", "message": "不能为空" }
  ]
}

带追踪的错误响应

{
  "success": false,
  "message": "用户不存在",
  "code": 404,
  "traceId": "req-abc123"
}

示例

运行演示示例:

# Actix-web 演示
cargo run --example actix_demo --features actix

# Axum 演示
cargo run --example axum_demo --features axum

# 检查示例
cargo check --examples --all-features

许可证

MIT