# 🏗️ Sdforge 架构文档
本文档描述 SDForge 的设计原则、系统架构、模块划分、数据流以及安全与性能设计。SDForge 是一个基于 Rust 的声明式多协议 SDK 框架:`#[forge]` 过程宏在编译期从统一的函数注解生成多协议(HTTP + MCP + gRPC + WebSocket + CLI)注册代码,未启用的协议不产生任何编译代码。使用视角的入门说明见[用户指南](USER_GUIDE.md)。
## 📋 目录
<details open>
<summary>📑 目录</summary>
- [概述](#-概述)
- [设计原则](#-设计原则)
- [系统架构](#️-系统架构)
- [模块划分](#-模块划分)
- [数据流](#-数据流)
- [安全设计](#-安全设计)
- [性能设计](#-性能设计)
</details>
## 🧭 概述
SDForge 由两个 crate 组成:
- **`sdforge-macros`**:过程宏 crate,实现 `#[forge]` / `#[service_module]`,负责解析注解并按 feature 门控生成各协议的注册代码
- **`sdforge`**:运行时库,提供各协议实现、核心类型、配置、安全与文档生成能力
框架的运行时骨架建立在 [inventory](https://crates.io/crates/inventory) 之上:宏生成的注册项(HTTP 路由、MCP 工具、gRPC handler、CLI 命令等)在编译期通过 `inventory::submit!()` 提交,应用启动时由 `init_all_plugins()` 一次性收集固化。
## 🧭 设计原则
1. **编译时协议选择** — 所有协议实现都由 `#[cfg(feature = "...")]` 门控。启用 `http` 不编译 MCP/gRPC/CLI 的任何代码;反之 `mcp`、`grpc`、`openapi`、`cli`、`streaming`、`cache` 也独立于 `http`(`#[forge(path=...)]` 生成的 HTTP 注册代码同样被 `#[cfg(feature = "http")]` 包裹)。量化收益:`http` only 相比 `full` 节省约 46–47% 编译时间、约六成库体积(见[编译期门控基准](benchmarks/vs-server-less.md))。
2. **统一接口定义** — 单个 `#[forge]` 注解描述端点,多协议各自消费同一份元数据(名称、版本、描述、参数 schema),消除跨协议的重复定义。
3. **Inventory 注册模式** — 编译期 `inventory::submit!()` 注册、运行期收集;`init_all_plugins()` 通过 `OnceLock` 缓存收集结果,防止 release 构建(LTO + 死代码消除)剔除注册项,并返回各协议注册计数用于自检。
4. **统一注册系统** — HTTP、MCP、WebSocket、gRPC 四大协议模块共享 `define_registration!` 宏与 `Registration` trait 抽象,消除重复样板代码。
5. **三种构造模式** — 所有组件必须支持 `new()`(开箱即用)、`builder()`(Builder 模式)、`with_dependencies()`(依赖注入)。
6. **不使用数据库** — 所有数据交互通过 oxcache(内存缓存)完成,框架自身零外部服务依赖;限流复用 limiteron,日志可桥接 inklog,依赖注入复用 trait-kit(`kit` feature)。
7. **统一 handler 契约** — 所有协议的 handler 遵循 `fn(HandlerArgs, HandlerState) -> HandlerFuture`:`HandlerArgs` 由 clap / tonic / axum extractor 构造,`HandlerState` 通过 `downcast_state::<T>()` 注入。
## 🏛️ 系统架构
模块注册与运行时装配全景:
```mermaid
flowchart TD
MAC["sdforge-macros 过程宏<br/>forge 与 service_module 注解解析"] -->|"cfg feature 门控生成"| REG["inventory 注册项<br/>HTTP 路由 MCP 工具 gRPC handler CLI 命令"]
REG --> BOOT["init_all_plugins<br/>inventory::iter 收集并以 OnceLock 固化"]
BOOT --> HTTP["http<br/>axum 路由与中间件栈"]
BOOT --> MCP["mcp<br/>rmcp 无状态 handler"]
BOOT --> GRPC["grpc<br/>tonic SdForgeGrpcService"]
BOOT --> CLI["cli<br/>clap CliBuilder"]
BOOT --> WS["websocket 与 streaming<br/>WS 与 SSE"]
CORE["core 与 error<br/>统一 handler 契约与错误类型"] --> HTTP
CORE --> MCP
CORE --> GRPC
CORE --> CLI
HTTP --> SEC["security ratelimit cache config<br/>health metrics graceful otel 等可选层"]
REG --> OAPI["openapi 与 docs<br/>OpenAPI 3.1 规范与 Swagger UI"]
```
仓库布局:
```text
sdforge/
├── src/ # 运行时库
├── macros/ # 过程宏 crate (#[forge])
├── examples/ # 综合示例库 (workspace member: sdforge-examples)
├── benches/ # 基准测试
├── proto/ # protobuf 定义 (gRPC)
├── docs/ # 文档(本目录)
├── tests/ # 集成/单元/宏测试
└── scripts/ # 构建和实用脚本
```
## 🧱 模块划分
| `core/` | 无 | 核心类型:`ServiceError` / `ServiceResponse`、`ApiMetadata`、统一 handler 契约(`handler.rs`)、inventory 注册抽象(`registration.rs`)、JSON 工具、`RegexCache`、校验(`validation.rs`) |
| `error/` | 无 | 框架错误:`ApiError`、`SdForgeError` / `SdForgeResult`、`ErrorContext`、错误 i18n |
| `domain/` | 无 | 领域抽象(如 `ForgeRateLimiter`),供集成层消费 |
| `i18n/` | `i18n`(格式化部分) | 翻译注册表(始终可用)+ ICU4X `HttpI18nFormatter` |
| `http/` | `http` | Axum 协议实现:`build()` / `build_with_config()`、版本路由、安全头、响应构造、路由注册 |
| `mcp/` | `mcp` | rmcp 集成:`StatelessServerHandler`、HTTP 头协议(`headers.rs`)、MRTR 会话(`mrtr.rs`)、缓存语义(`cache_semantics.rs`)、schema 校验 |
| `grpc/` | `grpc` | tonic 服务:`SdForgeGrpcService`、`GrpcServerConfig`、protobuf(`proto/sdforge.v1.proto`,`build.rs` 经 tonic-prost 生成到 `OUT_DIR`)、handler 注册与拦截器 |
| `websocket/` | `websocket` | 连接管理(`connection.rs`)、handler 分发(`handler.rs`)、广播(`broadcast.rs`)、消息解析(`message.rs`) |
| `streaming/` | `streaming` | SSE:`StreamEvent` / `StreamResponse`、`stream_to_sse`、`StreamBuilder` |
| `cli/` | `cli` | clap 集成:`CliBuilder`、`dispatch`、`GlobalArg`、docs 子命令 |
| `security/` | `security` / `ratelimit` / `ratelimit-http` | 认证(Bearer / API Key,`bearer/`、`types/`)、限流(limiteron 适配)、审计(`audit/`)、中间件 |
| `cache/` | `cache` | oxcache 透传与适配:`SyncCache` / `SharedCache` / `DashMapCache`、`ResponseCacheLayer` |
| `openapi/` | `openapi` | `OpenApiRouteInfo` 收集与 utoipa 规范生成、`OpenApiBuilder`、路径参数 schema 映射 |
| `docs/` | `docs` | 统一文档输出:Swagger UI 路由、CLI/MCP Markdown(`generate_docs` / `write_docs`) |
| `config/` | `http` | `AppConfig` / `ServerConfig` / `AuthConfig` / `CorsConfig` / `CacheConfig` 等模块化配置 + 集中默认值 + Builder |
| `logging.rs` | `logging` | `StructuredLogger`、全局 Logger |
| `inklog.rs` | `inklog` | 裸 `log` → inklog `LoggerManager` 桥接 |
| `integrations/` | `limiteron-integration` / `kit` | trait-kit AsyncKit 集成(`SdforgeModule`)、`LimiteronForgeAdapter` |
`macros/`(独立 crate):`#[forge]` / `#[service_module]` 解析、参数校验、路径参数提取与 schema 生成、按 feature 门控的多协议代码生成、trybuild 编译失败测试。
## 🔀 数据流
### 一份注解,五种协议
`#[forge]` 宏按当前启用的 feature 生成对应协议的注册项;未启用的协议不生成任何代码:
```mermaid
flowchart LR
A["forge 宏注解的 async 函数"] --> B["sdforge-macros 宏展开"]
B --> C["inventory 编译期注册"]
C --> D["http feature<br/>RouteRegistration axum 路由"]
C --> E["mcp feature<br/>McpToolRegistration 工具 schema"]
C --> F["grpc feature<br/>GrpcHandlerRegistration 调用分发"]
C --> G["cli feature<br/>CliCommandRegistration 子命令"]
C --> H["openapi feature<br/>OpenApiRouteInfo 规范收集"]
```
### 编译期
1. 开发者标注 `#[forge(name, version, path, method, ...)]`
2. 宏解析参数并校验(trybuild 覆盖编译失败用例)
3. 按启用的 feature 生成注册代码:
- `http` → `RouteRegistration`(路径/方法/版本)+ 路径参数提取器(多参数生成 `Path<(T1, ...)>` 元组按序解构;标量 Query 生成专用提取结构体)
- `mcp` → `McpToolRegistration` + `input_schema`(required / unknown-field 校验)
- `grpc` → `GrpcHandlerRegistration`(按 `grpc_method` 键)
- `cli` → `CliCommandRegistration` + `CliHandlerRegistration`(1:1 成对)
- `openapi` → `OpenApiRouteInfo`(含 `OpenApiPathParam`,路径 `:id` → `{id}`)
4. 全部注册项经 `inventory::submit!()` 进入编译产物
### 启动期
5. `main` 调用 `init_all_plugins()`:对每类注册项执行 `inventory::iter::<T>().collect()` 存入 `OnceLock<Mutex<Vec<&'static T>>>`(收集结果进程级缓存、幂等;Mutex 中毒时降级返回 0 而非连锁 panic),返回 `PluginCounts`
6. HTTP 侧 `http::build()` 依据 `RouteRegistration` 构建 Axum `Router`(含版本前缀 `/api/{version}` 与 `#[service_module]` 前缀拼接)
### 请求期(以 HTTP 为例)
7. 请求进入中间件栈:认证(`auth_middleware`,API Key / JWT Bearer)→ 限流(`RateLimitLayer`,基于 `ConnectInfo` 提取的 TCP 对端 IP)→ 安全头 / CORS / 超时
8. 版本路由匹配 `/api/{version}`,将请求分发到目标 handler;宏生成的提取器把路径/查询参数反序列化为函数参数
9. 统一 handler 契约执行:`HandlerArgs`(extractor 构造)+ `HandlerState`(`downcast_state` 注入)→ 业务函数 → `Result<T, ApiError>`
10. 响应管道:`ServiceResponse` 封装(显式 `status` / `success_with_status`)→ 可选 timestamp / logging / i18n 处理 → JSON 输出
```mermaid
sequenceDiagram
autonumber
participant C as 客户端
participant MW as 中间件栈
participant RT as 版本路由
participant FN as forge handler
participant RS as ServiceResponse
C->>MW: HTTP 请求
note over MW: auth_middleware 认证<br/>RateLimitLayer 限流<br/>安全头与 CORS
MW->>RT: 校验通过放行
RT->>FN: 匹配 /api/v1 路由<br/>提取路径与查询参数
FN->>FN: HandlerArgs 与 HandlerState<br/>执行业务逻辑
FN-->>RS: Result 值或 ApiError
RS-->>C: JSON 响应<br/>可选 timestamp i18n logging
```
其他协议入口复用 7–10 的后段:MCP 经 `Mcp-Method` / `Mcp-Name` 头(或 stdio)由 `StatelessServerHandler` 路由到同一批工具 handler;gRPC 经 `SdForgeGrpcService` 按 `grpc_method` 路由(载荷上限 1 MiB);CLI 经 `CliBuilder::execute()` 完成 parse → dispatch → `extract_value`(`Value::String` 输出原始串)→ 退出码。
## 🔒 安全设计
- **认证**:`security` feature 提供 API Key(版本管理、LRU 缓存、显式播种 `ApiKeySeed`、空库 fail-loud、过期反向索引强制)与 JWT Bearer(HMAC-SHA256 验签,`MIN_SECRET_LENGTH=32` 强制密钥长度)
- **fail-safe 默认值**:`ServerConfig` 默认绑定 `127.0.0.1`(而非 `0.0.0.0`);CORS 校验同时检查 scheme 与 host,`"http://"` 这类仅 scheme 的 origin 被拒绝
- **不可伪造的客户端 IP**:无 `ConnectInfo` 时不信任 `X-Forwarded-For` / `X-Real-IP`,直接返回 `None`,由调用方安全兜底;IP 限流/封禁只能基于 TCP 对端地址
- **审计**:`AuditLogger` 记录安全事件,支持 HMAC-SHA256 签名防篡改;密钥轮换动作有审计日志
- **错误脱敏**:`ApiError::Internal.message` 清洗后输出(不含路径/堆栈),`error_id` 供日志侧关联;`ErrorContext` 仅在服务端保留
- **输入防御**:MCP 工具 `input_schema` 的 required / unknown-field 校验;MCP 与 gRPC 载荷 1 MiB 上限;并发安全模式(Mutex/RwLock 中毒感知、缓存一致性锁序、usize 下溢防护)经系统化审计修复
- **供应链**:`cargo-audit` + `cargo-deny`(`deny.toml` 策略)+ Dependabot + CodeQL;发布前强制 tiangang SAST(0 CRITICAL)与 diting 审查(无 HIGH)
漏洞报告流程与安全最佳实践详见[安全文档](SECURITY.md)。
## ⚡ 性能设计
- **编译时裁剪是第一性能设计**:特性门控让未用协议的依赖(tonic/prost、rmcp、tokio-tungstenite、argon2/sha2 等)完全不进入编译图。实测(2026-07-03)`http` only 相比 `full` 节省约 47% 编译时间、约六成框架库体积,详见[编译期门控基准](benchmarks/vs-server-less.md)
- **运行期零协议税**:协议选择发生在编译期,不存在运行时协议探测或动态加载;运行时热路径基线见[性能基线](PERFORMANCE.md)
- **注册收集幂等缓存**:`init_all_plugins()` 用 `OnceLock` 缓存 inventory 迭代结果,重复调用零开销
- **正则缓存**:`core::RegexCache` 以 LRU 缓存编译后的正则(修复过 MRU 误驱逐缺陷),避免热路径重复编译
- **内存缓存**:oxcache 承载响应/工具结果缓存,支持键规范化、模式失效、批量操作与统计
- **发布 profile**:`lto = "fat"`、`codegen-units = 1`、`opt-level = 3`、`strip = true`,最大化内联与死代码消除(注意:链接期消除可稀释二进制层级的裁剪收益,但编译期成本节省不受影响)