资讯动态

用 ECC 的 Rust API CLAUDE.md 模板构建 Axum + SQLx + PostgreSQL 后端工程规范

发布时间:2026/9/10 16:05:33 来源:尧图企业网站定制
用 ECC 的 Rust API CLAUDE.md 模板构建 Axum SQLx PostgreSQL 后端工程规范【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC本文以 ECC 仓库中提供的 Rust API 服务项目模板examples/rust-api-CLAUDE.md 及其日文版 docs/ja-JP/examples/rust-api-CLAUDE.md为主体系统解析一个面向 Axum SQLx PostgreSQL Docker 的生产级 Rust 后端应如何组织工程规范、分层架构、错误处理、测试策略与 ECC 工作流。读者读完本文后可以直接把这份模板复制到自己的 Rust 项目根目录并定制同时理解每一条规则背后的源码级依据。模板定位一份可以直接落地定制的 CLAUDE.mdRust API 服务模板是 ECC 仓库examples/目录下的一组项目级 CLAUDE.md 样例之一与 django-api-CLAUDE.md、go-microservice-CLAUDE.md、rails-app-CLAUDE.md 等并列专门面向Rust Web 后端场景。官方说明非常明确Axum、PostgreSQL、Docker を使用したRust APIサービスの実世界サンプル。これをプロジェクトのルートにコピーしてサービスに合わせてカスタマイズしてください。 使用 Axum、PostgreSQL、Docker 的 Rust API 服务真实世界示例。请将其复制到项目根目录并根据你的服务进行定制。也就是说这份模板的典型用法是复制到你自己 Rust 项目的根目录命名为CLAUDE.md或等效的 Agent 指令文件然后按业务定制。它承担两类职责约束 Agent 行为把 Rust 工程的硬性规范禁止unwrap、参数化 SQL、thiserror错误模型、测试纪律等固化成规则让 Claude Code / Codex / Opencode / Cursor 等编码 Agent 在读写代码时遵守沉淀团队约定统一文件结构、命名、CI 命令、Git 提交流程降低多 Agent 协同时的认知成本。仓库中对这套规范还有更深一层的支撑体系rules/rust/目录下存放了 coding-style.md、patterns.md、security.md、testing.md、hooks.md 五份按文件路径**/*.rs自动生效的规则文件模板中的每一条约定几乎都能在规则目录里找到更完整的展开而 agents/rust-reviewer.md 则定义了专职的 Rust 代码评审 Agent。下文会逐一对照展开。技术栈与分层架构模板锁定的技术栈如下层次选型职责语言Rust 1.78内存安全、零成本抽象Web 框架Axum基于 Tokio/Tower 的异步 HTTP 框架路由 提取器 中间件数据库访问SQLx异步、编译期类型检查的 SQL 宏query!/query_as!数据库PostgreSQL关系型数据存储异步运行时Tokio异步任务调度与 IO部署Docker多阶段镜像构建scratch/distroless基础镜像架构上采用经典的分层架构Layered Architecture职责单向流动HTTP 请求 → Handler路由处理薄 → Service业务逻辑 → Repository数据访问 → PostgreSQL模板原文的表述是ハンドラー → サービス → リポジトリの分離を持つレイヤードアーキテクチャ。HTTPにAxum、コンパイル時に型チェックされたSQLにSQLx、横断的関心事にTowerミドルウェアを使用——即 Handler → Service → Repository 分离HTTP 交给 Axum编译期类型检查的 SQL 交给 SQLx横切关注点认证、日志、CORS 等交给 Tower 中间件。核心工程规范Critical Rules模板用一整节列出必须遵守的规则这是整份文档信息密度最高的部分。下面按主题逐条解析并补充规则目录中的依据。Rust 语言规约错误类型库代码用thiserror定义类型化错误anyhow只允许出现在二进制 crate 或测试中。这一点与 rules/rust/coding-style.md 的Error Handling一节完全一致Libraries: define typed errors withthiserrorApplications: useanyhowfor flexible error context。禁止生产代码使用.unwrap()/.expect()一律用?向上传播错误。对应的评审红线见 agents/rust-reviewer.md 的 CRITICAL 级别检查项 Uncheckedunwrap()/expect(): In production code paths — use?or handle explicitly。参数优先str所有权转移时才返回String减少不必要的克隆。规则目录中给出了典型正反例见 rules/rust/coding-style.md 的 Ownership and Borrowing 一节// GOOD — borrows when ownership isnt needed fn word_count(text: str) - usize { text.split_whitespace().count() } // BAD — takes String when str suffices fn word_count_bad(text: String) - usize { text.split_whitespace().count() }Clippy 从严启用#![deny(clippy::all, clippy::pedantic)]所有警告必须修复实践中等价于cargo clippy -- -D warnings。派生策略所有公开类型派生DebugClone/PartialEq仅在需要时派生。unsafe受限除非附有// SAFETY:注释说明不变量否则不得使用unsafe块。评审 Agent 将其列为必须阻止合并的 CRITICAL 项Unsafe without justification: Missing// SAFETY:comment documenting invariants。数据库规约数据库部分是安全红线最密集的区域所有查询必须用 SQLx 的query!/query_as!宏——SQL 会在编译期对照数据库 schema 校验字段类型不匹配直接编译失败迁移走migrations/目录 sqlx migrate禁止直接改动数据库共享状态用sqlx::PoolPostgres绝不允许每个请求新建连接所有查询使用参数化占位符$1、$2禁止字符串格式化拼 SQL。模板给出了正反两个例子这是全文最重要的安全示例之一完整继承如下// 悪い例: 文字列補間SQLインジェクションリスク // BAD: String interpolation (SQL injection risk) let q format!(SELECT * FROM users WHERE id {}, id); // 良い例: パラメータ化クエリ、コンパイル時チェック済み // GOOD: Parameterized query, compile-time checked let user sqlx::query_as!(User, SELECT * FROM users WHERE id $1, id) .fetch_optional(pool) .await?;在 rules/rust/security.md 的 SQL Injection Prevention 一节中规则进一步点明占位符语法随数据库后端而异Postgres 用$1MySQL 用?SQLite 用$1并补充了querybind的等价写法。这是把模板规则落地到非 Postgres 项目时需要特别注意的兼容点。错误处理规约模板要求用thiserror按模块定义领域错误枚举domain error enum通过IntoResponse把错误映射为 HTTP 响应绝不向客户端暴露内部细节结构化日志用tracing禁止println!/eprintln!。模板给出的AppError完整实现如下use thiserror::Error; #[derive(Debug, Error)] pub enum AppError { #[error(Resource not found)] NotFound, #[error(Validation failed: {0})] Validation(String), #[error(Unauthorized)] Unauthorized, #[error(transparent)] Internal(#[from] anyhow::Error), } impl IntoResponse for AppError { fn into_response(self) - Response { let (status, message) match self { Self::NotFound (StatusCode::NOT_FOUND, self.to_string()), Self::Validation(msg) (StatusCode::BAD_REQUEST, msg.clone()), Self::Unauthorized (StatusCode::UNAUTHORIZED, self.to_string()), Self::Internal(err) { tracing::error!(?err, internal error); (StatusCode::INTERNAL_SERVER_ERROR, Internal error.into()) } }; (status, Json(json!({ error: message }))).into_response() } }注意几个设计细节Internal用#[error(transparent)]#[from] anyhow::Error任何?传播上来的底层错误IO、SQLx、第三方 crate都能自动收敛进AppError配合#[from]免去手写map_err内部错误只记日志、不回传tracing::error!(?err, internal error)记录完整错误但响应体只返回泛化的Internal error避免把数据库报错、堆栈等敏感信息泄露给客户端。这与 rules/rust/security.md 的 Error Messages 一节要求一致Never expose internal paths, stack traces, or database errors in API responses. Log detailed errors server-side; return generic messages to clientsmatch显式映射 HTTP 状态码NotFound→404、Validation→400、Unauthorized→401、Internal→500语义清晰。如需统一响应信封{ status: ok, data: ... }或{ status: error, message: ... }rules/rust/patterns.md 的 API Response Envelope 一节提供了可复用的泛型枚举模式#[derive(Debug, serde::Serialize)] #[serde(tag status)] pub enum ApiResponseT: serde::Serialize { #[serde(rename ok)] Ok { data: T }, #[serde(rename error)] Error { message: String }, }测试规约单元测试写在每个源文件内的#[cfg(test)]模块中集成测试放在tests/目录使用真实 PostgreSQLTestcontainers 或 Docker数据库测试用#[sqlx::test]自动迁移 自动回滚外部服务用mockall或wiremock模拟。这与 rules/rust/testing.md 的测试组织方式一致单元测试与被测代码同文件集成测试每个文件是独立的二进制共享工具放tests/common/mod.rs。规则目录还补充了参数化测试rstest与属性测试proptest的推荐以及覆盖率的执行目标80% 行覆盖用 cargo-llvm-cov 统计--fail-under-lines 80可在 CI 强制门槛。代码风格规约最大行宽 100 字符rustfmt 强制导入分组std→ 外部 crate →crate/super组间空行分隔模块组织一个模块一个文件mod.rs只做再导出re-export命名类型 PascalCase、函数/变量 snake_case、常量 UPPER_SNAKE_CASE。此外 rules/rust/coding-style.md 还补充了模块按领域domain而非按类型组织的建议以及可见性纪律Default to private; usepub(crate)for internal sharing; only markpubwhat is part of the crates public API; re-export public API fromlib.rs。这与模板文件结构中domain/、services/、repositories/的划分思路完全同构。文件结构模板的目录蓝图模板给出了完整的目录树原文结构逐行继承src/ main.rs # エントリーポイント、サーバーセットアップ、グレースフルシャットダウン lib.rs # 統合テスト用の再エクスポート config.rs # envyまたはfigmentによる環境設定 router.rs # すべてのルートを持つAxumルーター middleware/ auth.rs # JWT抽出とバリデーション logging.rs # リクエスト/レスポンスのトレーシング handlers/ mod.rs # ルートハンドラー薄く — サービスに委任 users.rs orders.rs services/ mod.rs # ビジネスロジック users.rs orders.rs repositories/ mod.rs # データベースアクセスSQLxクエリ users.rs orders.rs domain/ mod.rs # ドメイン型、エラーenum user.rs order.rs migrations/ 001_create_users.sql 002_create_orders.sql tests/ common/mod.rs # 共有テストヘルパー、テストサーバーセットアップ api_users.rs # ユーザーエンドポイントの統合テスト api_orders.rs # 注文エンドポイントの統合テスト解读几个关键设计lib.rs专门为集成测试服务把路由、状态等从main.rs抽出再导出tests/里的集成测试才能直接usecrate 内部类型并启动测试服务这是 Rust 集成测试的常见手法config.rs用envy或figment做环境配置环境变量到类型化配置结构的解析集中在这一处middleware/auth.rs承担 JWT 提取与校验对应模板架构说明中横切关注点交给 Tower 中间件的落点domain/与repositories/分离领域类型含错误枚举与数据访问互不污染rules/rust/patterns.md 中建议用 trait 封装仓储以便测试时替换为内存实现。关键模式Handler → Service → Repository 三层Handler保持轻薄Handler 只做解包请求、调服务、包响应三件事业务逻辑一律下放async fn create_user( State(ctx): StateAppState, Json(payload): JsonCreateUserRequest, ) - Result(StatusCode, JsonUserResponse), AppError { let user ctx.user_service.create(payload).await?; Ok((StatusCode::CREATED, Json(UserResponse::from(user)))) }注意StateAppState提取器注入共享状态内含服务实例Json提取器自动反序列化请求体并处理 400 校验错误返回类型Result..., AppError由前文IntoResponse统一接管错误渲染。测试时可用tower::ServiceExt的oneshot直接对 Router 发起请求。Service业务逻辑Service 承载可测试的业务规则。模板示例展示了查重 → 哈希 → 入库的完整业务流impl UserService { pub async fn create(self, req: CreateUserRequest) - ResultUser, AppError { if self.repo.find_by_email(req.email).await?.is_some() { return Err(AppError::Validation(Email already registered.into())); } let password_hash hash_password(req.password)?; let user self.repo.insert(req.email, req.name, password_hash).await?; Ok(user) } }这里值得注意的设计业务不变量邮箱唯一由 Service 层保证而非依赖数据库唯一约束兜底从而可以先用mockall模拟 Repository 做纯单元测试再在集成测试中验证真实约束。rules/rust/patterns.md 的 Service Layer 模式进一步建议通过构造函数注入依赖Boxdyn OrderRepository、Boxdyn PaymentGateway把外部副作用完全隔离开。Repository数据访问Repository 是唯一接触 SQL 的地方全部使用编译期校验宏impl UserRepository { pub async fn find_by_email(self, email: str) - ResultOptionUser, sqlx::Error { sqlx::query_as!(User, SELECT * FROM users WHERE email $1, email) .fetch_optional(self.pool) .await } pub async fn insert( self, email: str, name: str, password_hash: str, ) - ResultUser, sqlx::Error { sqlx::query_as!( User, r#INSERT INTO users (email, name, password_hash) VALUES ($1, $2, $3) RETURNING *#, email, name, password_hash, ) .fetch_one(self.pool) .await } }query_as!的返回值会按User结构体在编译期做类型比对RETURNING *让 INSERT 直接返回完整实体省一次回查。若希望为上层提供可 mock 的抽象rules/rust/patterns.md 的 Repository Pattern with Traits 给出了 trait 化写法——把find_by_id、save、delete等操作声明为 traitPostgres/SQLite/内存实现可互换测试时替换为内存实现即可。配合Parse, dont validate的输入校验哲学见 rules/rust/security.md可以在domain/层用 newtype 让非法状态不可表示例如Email(String)的构造函数只接受通过校验的输入非法邮箱在类型层面就无法进入 Service。集成测试实战模板给出了基于真实 PostgreSQL 的集成测试样例覆盖成功创建与重复邮箱两条路径#[tokio::test] async fn test_create_user() { let app spawn_test_app().await; let response app .client .post(format!({}/api/v1/users, app.address)) .json(json!({ email: aliceexample.com, name: Alice, password: securepassword123 })) .send() .await .expect(Failed to send request); assert_eq!(response.status(), StatusCode::CREATED); let body: serde_json::Value response.json().await.unwrap(); assert_eq!(body[email], aliceexample.com); } #[tokio::test] async fn test_create_user_duplicate_email() { let app spawn_test_app().await; // Create first user create_test_user(app, aliceexample.com).await; // Attempt duplicate let response create_user_request(app, aliceexample.com).await; assert_eq!(response.status(), StatusCode::BAD_REQUEST); }两个用例共同依赖tests/common/mod.rs中的spawn_test_app()——它负责用 Testcontainers/Docker 拉起真实 PostgreSQL、执行迁移、构建 Axum Router 并返回测试客户端与监听地址。第二个用例验证的是 Service 层的查重逻辑对应AppError::Validation→ 400属于典型的行为驱动断言断言 HTTP 状态码而非内部实现。对需要模拟外部 HTTP 服务的场景模板推荐wiremock对需要 mock trait 的场景rules/rust/testing.md 给出了mockall的用法——生产代码定义pub trait UserRepository测试模块内用mockall::mock!生成MockRepo再用expect_find_by_id().with(eq(42)).times(1).returning(...)精确编排期望调用。这正是上面UserService::create脱离数据库做单元测试的基础。环境变量清单模板把运行时配置全部收敛为环境变量共四组# サーバー / Server HOST0.0.0.0 PORT8080 RUST_LOGinfo,tower_httpdebug # データベース / Database DATABASE_URLpostgres://user:passlocalhost:5432/myapp # 認証 / Auth JWT_SECRETyour-secret-key-min-32-chars JWT_EXPIRY_HOURS24 # 任意 / Optional CORS_ALLOWED_ORIGINShttp://localhost:3000关键约束解读JWT_SECRET要求至少 32 字符HS256 类签名算法对密钥长度的硬性要求低于该长度应启动即失败DATABASE_URL是 SQLx 的连接串sqlx::PoolPostgres在启动时由此建立连接池模板要求连接池作为共享状态注入禁止按请求建连RUST_LOG控制tracing过滤级别示例中info,tower_httpdebug表示全局 info、tower_http 中间件日志开到 debug便于排查请求级问题CORS_ALLOWED_ORIGINS可选配置跨域白名单由 Tower 中间件消费。agents/rust-reviewer.md 的 CRITICAL 项同样强调 Hardcoded secrets: API keys, passwords, tokens in source 必须阻止合并与模板配置走环境变量的约定互为表里。测试策略与常用命令模板给出了一套完整的命令矩阵逐条继承可直接进入 CI 或本地开发流程# すべてのテストを実行 / Run all tests cargo test # 出力付きで実行 / Run with output cargo test -- --nocapture # 特定のテストモジュールを実行 / Run specific test module cargo test api_users # カバレッジチェックcargo-llvm-covが必要/ Check coverage cargo llvm-cov --html open target/llvm-cov/html/index.html # リント / Lint cargo clippy -- -D warnings # フォーマットチェック / Format check cargo fmt -- --check按 rules/rust/testing.mdcargo test还能细分cargo test --lib只跑单元测试、cargo test --test api_test只跑指定集成测试、cargo test --doc跑文档测试。而cargo clippy -- -D warnings与cargo fmt -- --check也是 ECC 的 rust-reviewer 在评审任何 Rust 改动时首轮必跑的门禁命令——见 commands/code-review.md 中针对 Rust 项目的验证段cargo clippy -- -D warnings、cargo test、cargo build。与 ECC 工作流集成模板专门给出了ECC 工作流一节把日常开发串成 Agent 可执行的命令链# 計画 / Planning /plan Add order fulfillment with Stripe payment # TDDによる開発 / Development with TDD /tdd # cargo test ベースのTDDワークフロー # レビュー / Review /code-review # Rust固有のコードレビュー /security-scan # 依存関係監査 unsafeスキャン # 検証 / Verification /verify # ビルド、clippy、テスト、セキュリティスキャン这套命令在 ECC 仓库中均有真实实现可对照阅读/plan对应 commands/plan.md在动手写代码前完成需求拆解与实现计划/code-review对应 commands/code-review.md支持本地未提交改动评审与 GitHub PR 评审两种模式。对 Rust 项目会自动执行cargo clippy -- -D warnings、cargo test、cargo build作为验证门禁评审维度覆盖正确性、类型安全、模式合规、安全、性能、完整性、可维护性七类CRITICAL/HIGH 问题未修复前不允许合并/security-scan对应 commands/security-scan.md运行 AgentShield 扫描重点覆盖硬编码密钥、越权权限、危险依赖与 unsafe 面支持--format json接入 CI、--min-severity过滤、--fix自动修复安全标记为安全的项/verify把构建、clippy、测试、安全扫描合并为一次收口验证。值得强调的是ECC 还针对 Rust 提供了专职评审 Agent agents/rust-reviewer.md其审查优先级与模板规则一一对应CRITICAL 层检查未受检unwrap、无SAFETY注释的 unsafe、SQL 注入、硬编码密钥等HIGH 层检查所有权/生命周期滥用、async 中阻塞调用、无界 channel、大函数深嵌套等MEDIUM 层检查无谓分配、N1 查询、clippy 警告被无理由 suppress 等。评审结论分三档无 CRITICAL/HIGH 即 Approve、仅 MEDIUM 即 Warning、有 CRITICAL/HIGH 即 Block。Git 工作流与 CI/部署模板最后规定了提交与交付纪律提交类型feat:新功能、fix:缺陷修复、refactor:代码重构分支策略从main拉取功能分支合并必须走 PRCI 门禁cargo fmt --check→cargo clippy→cargo test→cargo audit依赖漏洞审计部署Docker 多阶段构建基础镜像选scratch或distroless产出最小化、无 shell 的攻击面。其中cargo audit属于依赖安全基线rules/rust/security.md 的 Dependency Security 一节进一步推荐了完整的依赖治理组合cargo audit已知 CVE 扫描、cargo deny check许可证与 advisory 合规、cargo tree -d排查重复依赖版本并建议接入 Dependabot/Renovate 持续更新依赖、新增依赖前先评估必要性。小结ECC 的这份 Rust API 模板并不是一份泛泛的代码风格文档而是一套可复制、可定制、有实现支撑的工程闭环从技术栈与分层架构出发用 Critical Rules 约束代码质量与安全底线编译期 SQL 校验、类型化错误、禁止裸 unwrap/unsafe用目录蓝图固定模块边界用 Handler→Service→Repository 三件套与集成测试样例示范落地写法再通过环境变量、测试命令矩阵、ECC 工作流与 Git/CI 纪律把工程规范固化成日常动作。如果你正在用 Rust 构建 Axum 后端可以直接复制 examples/rust-api-CLAUDE.md 到项目根目录并对照 rules/rust/、agents/rust-reviewer.md 与 commands/code-review.md、commands/security-scan.md 完成团队级、可审计的工程治理。【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价