Files
Genarrative/server-rs/crates/api-server

api-server 主工程 crate 占位说明

日期:2026-04-20

1. crate 职责

api-server 是新后端的 Axum 主工程 crate后续负责

  1. main.rs 启动入口
  2. Router 装配
  3. with_state 共享状态注入
  4. 中间件挂载
  5. /healthz/api/*、SSE 与静态资源兼容层装配
  6. ../../scripts/dev.ps1../../scripts/dev.sh 驱动的本地开发启动链路
  7. ../../scripts/test.ps1../../scripts/test.sh 驱动的本地测试链路
  8. ../../scripts/check.ps1../../scripts/check.sh 驱动的本地统一检查链路
  9. ../../scripts/smoke.ps1../../scripts/smoke.sh 驱动的本地启动与协议冒烟链路

2. 当前阶段说明

当前目录已经完成以下基础骨架:

  1. 目录占位
  2. Cargo.toml
  3. src/main.rs
  4. src/app.rs
  5. src/state.rs
  6. src/config.rs
  7. 基础 TraceLayer 挂载
  8. 接入 shared-logging 完成 tracing subscriber 初始化

后续与本 crate 直接相关的任务包括:

  1. 接入统一日志与 tracing
  2. 接入 request_id
  3. 接入统一错误处理中间件
  4. 接入 response envelope
  5. 接入 /healthz

当前 tracing 约定:

  1. 进程启动时通过 shared-logging 统一初始化 tracing subscriber
  2. 默认日志过滤器来自 GENARRATIVE_API_LOG,未提供时回落到 info,tower_http=info
  3. HTTP 访问日志统一通过 Axum 路由层的 TraceLayer 输出,后续 request_id、响应头与错误中间件继续在同一层扩展。

当前 request context 约定:

  1. 中间件优先读取来访 x-request-id,未提供时生成新的 UUID。
  2. request_id 会统一写入请求 extensions 与请求头,供 tracing、错误处理中间件和响应头层复用。
  3. 最终响应会回写同一个 x-request-id,保证调用方、日志链路和后续 envelope meta.requestId 可对齐。

当前错误处理中间件约定:

  1. 对 Axum 默认产生的空 4xx / 5xx 响应,统一归一化为 legacy 兼容 JSON 错误体:{ error: { code, message, details? } }
  2. 已经带 content-type 的业务错误响应不会被覆盖,避免抢走后续 response envelope 的职责。
  3. 统一错误日志会复用当前请求的 request_id便于后续和响应头、envelope 元信息串联。

当前 response envelope 约定:

  1. RequestContext 已记录 request_id、请求开始时间、默认 operation 与 envelope 协商结果。
  2. json_success_body(...) / json_error_body(...) 会根据 x-genarrative-response-envelope 自动在“裸数据 / 标准 envelope / legacy error + meta”之间切换。
  3. meta.apiVersionmeta.requestIdmeta.routeVersionmeta.operationmeta.latencyMsmeta.timestamp 已按当前前端契约生成,响应头回写仍留给后续独立任务。

当前基础响应头约定:

  1. 所有响应都会回写 x-request-id
  2. 所有响应都会回写固定的 x-api-version,当前值与 body meta.apiVersion 保持一致。
  3. 所有响应都会回写 x-route-version,当前阶段默认与 x-api-version 保持一致,后续再按路由粒度细分。
  4. 所有响应都会回写 x-response-time-ms,值来源于 RequestContext 内记录的请求开始时间。

当前 /healthz 约定:

  1. 路径固定为 /healthz
  2. 裸响应继续返回 { ok: true, service: "genarrative-node-server" },保持与当前 Node 工程兼容。
  3. 当请求携带 x-genarrative-response-envelope 时,/healthz 会返回标准 success envelope。
  4. x-request-idx-api-versionx-route-versionx-response-time-ms 会在 /healthz 响应中一并回写。

当前本地检查链路约定:

  1. ../../scripts/check.ps1../../scripts/check.sh 统一串联 cargo fmt --all --checkcargo clippycargo checkcargo test
  2. 默认检查整个 server-rs workspace确保后续多 crate 扩容时仍然保持统一口径。
  3. 当只需聚焦单个 crate 时,可通过 -PackageSERVER_RS_CHECK_PACKAGE 收窄 clippy / check / test 目标。
  4. cargo fmt --all --check 仍固定覆盖整个 workspace避免多 crate 下格式基线漂移。

当前本地 smoke 链路约定:

  1. ../../scripts/smoke.ps1../../scripts/smoke.sh 会先构建 api-server,再拉起临时本地进程完成冒烟验证。
  2. smoke 当前固定校验 /healthz 的 raw 响应、envelope 响应以及 x-request-idx-api-versionx-route-versionx-response-time-ms 头。
  3. smoke 通过后可作为“Axum 服务可独立启动且基础 contract 可联通”的本地自动化证据。

3. 边界约束

  1. api-server 负责 HTTP、SSE、Cookie、Header、路由与协议装配。
  2. 业务逻辑优先通过独立模块 crate 暴露能力,再由主工程组合。
  3. 外部副作用通过 platform-authplatform-ossplatform-llm 与各模块 crate 的应用层完成。
  4. 不把领域规则直接堆在 handler 中。