aster_forge_api
aster_forge_api 提供框架无关的 API response helper,当前重点是分页、cursor、排序和 OpenAPI schema 条件派生。
它不依赖 Actix、Axum 或产品实体,handler 层只需要把请求参数映射成这些通用结构,再把结果包装回产品响应。
适用场景
- limit/offset 分页。
- cursor 分页。
- 常见 cursor 参数解析。
- PATCH 请求三态字段。
- 列表响应结构。
SortOrder的稳定序列化。- debug +
openapifeature 下的utoipaschema 派生。
不适合放在这里的内容:
- 产品列表默认排序规则。
- 权限过滤。
- 数据库查询本身。
- API 错误状态码和本地化文案。
Cargo feature
[dependencies]
aster_forge_api = { git = "https://github.com/AsterCommunity/AsterForge" }OpenAPI 构建:
aster_forge_api = { git = "https://github.com/AsterCommunity/AsterForge", features = ["openapi"] }openapi 只在 debug_assertions 下启用 utoipa 派生,避免 release binary 拉入文档生成负担。
分页参数
常用类型:
LimitOffsetQueryLimitQueryOffsetPage<T>CursorPage<T, C>
典型接入:
let limit = query.limit();
let rows = repo::list(limit + 1).await?;
let page = aster_forge_api::CursorSlice::from_overfetched(rows, limit);产品侧仍然负责:
- 查询时多取一条还是单独 count。
- cursor 字段对应哪个数据库索引。
- 是否允许客户端指定更大 limit。
Cursor 解析
常用函数:
parse_id_cursorparse_string_id_cursorparse_datetime_id_cursorparse_datetime_string_cursorparse_sort_order_name_id_cursorparse_enabled_priority_id_cursor
这些函数只做参数完整性校验。例如传了 after_id 却没传配套 timestamp,会返回 ApiError。产品侧应在 handler/service 边界把 ApiError 映射为自己的 bad request 错误。
排序
SortOrder 只表达 Asc / Desc,不表达产品字段名。字段白名单应该留在产品仓库,不要让客户端传任意列名后直接拼到数据库层。
PATCH 三态字段
类型:
NullablePatch<T>deserialize_nullable_patch_option
NullablePatch<T> 用于区分 PATCH DTO 中的三种状态:
Absent:字段未传,保持原值。Null:字段显式传入null,清空原值。Value(T):字段传入具体值,更新为新值。
常见写法:
#[derive(serde::Deserialize)]
struct UpdateItemRequest {
#[serde(default)]
title: aster_forge_api::NullablePatch<String>,
#[serde(
default,
deserialize_with = "aster_forge_api::deserialize_nullable_patch_option"
)]
description: Option<aster_forge_api::NullablePatch<String>>,
}如果字段本身不是 Option,直接用 #[serde(default)] 即可。字段本身需要 Option<NullablePatch<T>> 时,使用 deserialize_nullable_patch_option() 保留显式 null。
产品 service 应该在更新逻辑里显式匹配三态,不要把 Null 和 Absent 混掉。
OpenAPI 接入
如果产品启用 OpenAPI:
[features]
openapi = ["aster_forge_api/openapi"]然后把分页类型直接放进 route query 或 response schema。没有启用 feature 时,ApiSchema 是空 trait,不影响普通编译。
测试要求
- cursor 参数成对出现的错误路径。
- limit clamp 到产品允许范围。
- PATCH DTO 中 omitted/null/value 三态。
- overfetch 后
next_cursor是否正确。 - OpenAPI feature 下 schema 编译通过。
参考项目
- AsterDrive:文件、文件夹、分享、任务列表等 cursor 分页。
- AsterYggdrasil:管理员任务和用户列表等较轻 API。