affaanm-backend-patterns
后端架构模式、API 设计、数据库优化、服务端最佳实践。
评分明细
适用场景
affaanm-backend-patterns 快速入门
把 10 个月真实生产项目里踩过的坑,变成 AI 直接可用的后端架构模式。
这是什么?解决什么问题?
affaanm-backend-patterns 是 affaan-m/everything-claude-code 仓库下的一个 Skill。它的来历比较有意思:作者 affaan-m 带着这个项目拿过 Anthropic 黑客马拉松奖项,在 10 个月里持续用 Claude Code 写后端,沉淀了 10+ 真实生产配置,最后把这些”反复出现的模式”打包成 Skill。
它解决的问题是:AI 写后端代码时,默认倾向”教科书式”的简单实现——直接把所有逻辑塞进一个 controller、用全局变量缓存、SQL 拼接、错误信息吞掉……这些在 demo 里没问题,生产环境分分钟爆。
这个 Skill 沉淀的实战模式包括:
- API 设计:REST 命名规范、版本号策略、错误响应统一格式。
- 数据库优化:索引选择、N+1 查询规避、事务边界。
- 服务架构:分层架构(controller / service / repository)、依赖注入。
- 可观测性:结构化日志、trace_id 串联、metrics 埋点。
- 韧性设计:超时、重试、熔断、降级、限流。
它适合的场景:中大型后端项目的架构定型、AI 写新需求时希望遵循团队已有规范、Code Review 时希望 AI 主动指出”教科书式实现”的风险。
准备工作
- 一个支持 Skill 加载的 AI 编程助手(Claude Code / Cursor / Cline 等)。
- 你的项目里已经有清晰的分层结构,或者愿意按照 Skill 的建议从零开始。
- Clone 仓库:
git clone https://github.com/affaan-m/everything-claude-code.git - 软链 Skill:
ln -s everything-claude-code/skills/backend-patterns ~/.claude/skills/backend-patterns
3 步快速上手
第 1 步:安装 Skill
按上面的命令软链完成后,重启 AI 助手,Skill 自动生效。
第 2 步:验证安装
向 AI 发送请求:
“请用 affaanm-backend-patterns 的风格,给我一段 FastAPI 用户注册接口,要求分 controller / service / repository 三层,事务边界清晰。”
如果 AI 输出包含三个明确的目录/文件分层、显式的 with db.begin(): 事务块、统一的 ErrorResponse schema,说明 Skill 加载成功。
第 3 步:用 Skill 跑第一个任务
假设你要做一个 Python + FastAPI + SQLAlchemy 的用户注册接口,让 AI 帮你按这个 Skill 的模式产出代码骨架:
app/
├── controllers/
│ └── user_controller.py # 路由层
├── services/
│ └── user_service.py # 业务逻辑层
├── repositories/
│ └── user_repository.py # 数据访问层
├── schemas/
│ └── user.py # Pydantic 模型
└── errors.py # 统一错误响应
user_repository.py:
from sqlalchemy.orm import Session
from app.models import User
class UserRepository:
def __init__(self, db: Session):
self.db = db
def get_by_email(self, email: str) -> User | None:
return self.db.query(User).filter(User.email == email).first()
def create(self, user: User) -> User:
self.db.add(user)
self.db.flush()
return user
user_service.py:
from app.repositories.user_repository import UserRepository
from app.errors import ConflictError
class UserService:
def __init__(self, repo: UserRepository):
self.repo = repo
def register(self, email: str, password: str) -> int:
if self.repo.get_by_email(email):
raise ConflictError("email already exists")
user = User(email=email, password_hash=hash_password(password))
with self.repo.db.begin():
self.repo.create(user)
return user.id
Skill 会提醒 AI:“不要在 service 层直接 commit,要由调用方或外层事务统一管理”——这就是它和教科书实现的差异。
常见踩坑
- 把所有逻辑塞进 controller。一个函数 200 行,业务、SQL、序列化全混在一起,Skill 明确反对这种”上帝 controller”。
- service 层直接 commit 事务。事务边界应该在外层(incoming request)统一管理,否则嵌套调用时容易出现”半提交”状态。
- 错误用字符串而不是异常类。
return {"error": "not found"}很难做全局错误处理,Skill 建议定义异常类 + 全局异常处理器。 - 数据库连接在每个请求里新建。FastAPI 依赖注入
Depends(get_db)是正确姿势,别在 controller 里手动Session()。 - 缺 trace_id。生产环境排障时没有 trace_id 串联,日志就是黑盒。Skill 强调每个请求都要生成
X-Request-ID。 - 同步阻塞调用放在异步接口里。FastAPI 的
async def路由里用requests.get这种同步库,会阻塞整个事件循环。
初级用法
用法 1:搭新项目的目录骨架。让 AI 按 backend-patterns 的分层模板,生成一个新项目的完整目录结构。
用法 2:重构老的”大泥球”controller。把一个 300 行的 controller 贴给 AI,让它按 Skill 拆成 controller + service + repository 三层。
用法 3:统一错误响应格式。让 AI 帮你设计全局 ErrorResponse 和异常处理装饰器,前端就能用统一的格式解析错误。
高级玩法
玩法 1:CQRS 模式。对读多写少的场景,把 query 和 command 拆到不同 service,query 可以走读副本、cache,command 走主库,Skill 里有相应模板。
玩法 2:Outbox 模式。解决”本地事务 + 消息发送”的数据一致性问题,先写 outbox 表,异步 worker 投递到 MQ。
玩法 3:多租户隔离。在 repository 层强制注入 tenant_id 过滤条件,避免越权访问。Skill 建议用 SQLAlchemy event 或 Django middleware 实现。
小技巧
- 依赖注入用类型注解。FastAPI 的
Depends(get_service)比手写service = UserService()更易测试。 - Pydantic schema 双向分离。
UserCreate(入参)、UserOut(出参)分开,避免内部字段泄露到 API。 - 日志用结构化格式。
logger.info("user_registered", extra={"user_id": uid, "email": email}),方便后续接 ELK / Loki。 - 慢查询埋点。在 SQLAlchemy event 里监听
before_cursor_execute,记录> 100ms的查询,定期 review。 - 不要在 Skill 里硬编码项目专属命名。Skill 给的是模板,记得替换成你自己项目的命名风格(比如有些团队把 service 叫
usecase)。
常见问题 FAQ
Q1: 这个 Skill 跟 affaanm-backend-patterns 有什么关系?必须装吗?
A: Skill 是给 AI Agent 用的”技能包”,能告诉 Agent 怎么按特定规范工作。不是必须装——如果你的项目规模小、要求不高,不装也能用。但装上能让 Agent 输出的质量更高、更符合最佳实践,推荐装。
Q2: 这个 Skill 适合哪些 AI Agent?Cursor?Claude Code?其他?
A: affaanm-backend-patterns 来自 community,主要面向支持 Skill 机制的 Agent。常见兼容 Agent 包括 Claude Code、Cursor、OpenCode、Windsurf 等。具体兼容性请查 Skill 官方文档。
Q3: 装了这个 Skill 后,会拖慢 Agent 响应吗?
A: 会的——Skill 通常会增加 prompt 长度,导致响应变慢、token 消耗增加。但质量提升明显。建议:1) 只装项目必需的 Skill;2) 用 Skill 启动/加载/卸载机制按需加载;3) 定期清理不用的 Skill。
Q4: 怎么验证 Skill 装对了?
A: 在 Agent 中输入”列出已加载的 Skill”或类似命令。如果 Skill 出现在列表里,说明装对了。然后用 Skill 跑一个相关任务,看输出是否符合 Skill 规范。
Q5: 这个 Skill 有许可证吗?能商用吗?
A: 取决于 affaanm-backend-patterns 的许可证。常见许可证包括 MIT(完全自由)、Apache-2.0(自由但有专利条款)、源可用(可看不能用)、GPL(强开源)。商用前请查仓库 LICENSE 文件。
进阶学习建议
如果想进一步用好 affaanm-backend-patterns,建议按以下路径学习:
第 1 周:熟练使用
- 完成 3 步快速上手,跑通第一个任务
- 试 2-3 个不同场景的真实任务
- 记录”哪些 prompt 有效、哪些没用”——形成自己的 prompt 笔记
第 2 周:理解机制
- 阅读 Skill 的官方文档(README、SKILL.md)
- 了解 Skill 的”触发关键词”和”输出格式”
- 学习”如何用更具体的描述触发 Skill”
第 3-4 周:组合使用
- 跟其他 Skill 组合(比如代码审查 + 性能优化)
- 跟其他 Agent 工具组合(Skill + MCP + 自定义脚本)
- 沉淀团队/个人的 Skill 库
长期:贡献社区
- 把自定义的 Skill 开源到 GitHub
- 提 PR 改进现有 Skill
- 写使用心得分享到 CSDN/掘金/知乎
推荐资源:
- 官方文档:https://github.com/affaan-m/everything-claude-code
- 官方仓库 README 里的 Examples
- 社区最佳实践:Anthropic 官方博客 https://www.anthropic.com/blog
- 国内社区:CSDN AI 板块、掘金 AI 板块
避免的坑:
- 不要装太多 Skill(超过 10 个会拖慢 Agent)
- 不要把 Skill 装在不兼容的 Agent 上
- 不要直接复制 Skill 默认 prompt——要根据项目调整
- 定期 review Skill 库的实用性,清理不用的
参考链接
- affaanm-backend-patterns 仓库:https://github.com/affaan-m/everything-claude-code
- Skill 路径:https://github.com/affaan-m/everything-claude-code/tree/main/skills/backend-patterns
- FastAPI 官方文档:https://fastapi.tiangolo.com/
- SQLAlchemy 2.0 异步模式:https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html
- 12-Factor App:https://12factor.net/
本文基于官方文档和公开资料整理,AI辅助生成,MagicNetWorld 尚未完成独立实测。如有错误或过时信息,请通过 contact@magicnetworld.com 反馈。
backend-patterns Skill 多维度简评
类别:后端开发 / 架构 仓库:affaan-m/everything-claude-code 维护者:affaan-m(Anthropic 黑客马拉松获胜者) 含金量:经过 10+ 个月构建真实产品演化
一、核心定位与价值
这不是”AI 写的后端模板”——这是Anthropic 黑客马拉松获胜者在他真实生产项目中使用 10 个月后沉淀下来的后端架构最佳实践。
它的价值在于:
- ✅ 真实战场验证:不是 demo,是 10000+ 行生产代码
- ✅ 跨语言适用:Node.js / Python / Go / Java 都用得上
- ✅ 覆盖完整 SDLC:从 API 设计到部署监控
- ✅ 可量化:每条规则都有反例和正例
二、SKILL.md 标准结构
---
name: backend-patterns
description: Backend architecture patterns, API design, database optimization,
and server-side best practices. Use when designing or implementing backend services.
license: MIT
---
完整 SKILL.md 包含:
- Overview - 概述与适用场景
- When to Use - 何时触发
- Patterns - 具体的模式集合
- Anti-Patterns - 反模式
- Examples - 完整示例代码
- References - 详细参考
三、12 大核心模式
模式 1:REST API 资源命名
原则:资源用名词复数,不是动词
✅ GET /api/v1/users
✅ POST /api/v1/users
✅ GET /api/v1/users/:id
✅ PUT /api/v1/users/:id
✅ PATCH /api/v1/users/:id
✅ DELETE /api/v1/users/:id
❌ GET /api/v1/getUsers
❌ POST /api/v1/createUser
❌ GET /api/v1/userList
模式 2:状态码语义化
| 场景 | 状态码 |
|---|---|
| 成功 | 200 OK |
| 创建成功 | 201 Created |
| 删除成功(无 body) | 204 No Content |
| 客户端错误(语法错误) | 400 Bad Request |
| 未认证 | 401 Unauthorized |
| 已认证但无权限 | 403 Forbidden |
| 资源不存在 | 404 Not Found |
| 资源冲突(重复) | 409 Conflict |
| 验证失败 | 422 Unprocessable Entity |
| 服务器错误 | 500 Internal Server Error |
模式 3:分页策略
Cursor-based(推荐用于大数据):
GET /api/v1/users?cursor=eyJpZCI6MTAwfQ&limit=20
Response:
{
"data": [...],
"next_cursor": "eyJpZCI6MTIwfQ",
"has_more": true
}
Offset-based(适合小数据):
GET /api/v1/users?page=1&page_size=20
Response:
{
"data": [...],
"pagination": {
"page": 1,
"page_size": 20,
"total": 1523,
"total_pages": 77
}
}
模式 4:过滤 / 排序
GET /api/v1/users?status=active&role=admin&sort=-created_at,name
支持的查询参数:
- 字段=值:精确匹配
- 字段[in]=a,b,c:包含
- 字段[gt]=10:大于
- 字段[between]=10,20:范围
- sort=-field,field:负号降序
模式 5:统一错误响应
{
"error": {
"code": "INVALID_INPUT",
"message": "邮箱格式不正确",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "邮箱必须包含 @"
}
],
"request_id": "req_abc123",
"timestamp": "2026-06-15T12:34:56Z"
}
}
关键:
code:机器可读(PROGRAMMABLE)message:人类可读details:字段级错误request_id:用于追踪- 不要泄露内部栈
模式 6:API 版本控制
3 种策略对比:
| 策略 | URL 示例 | 优点 | 缺点 |
|---|---|---|---|
| URL Path | /api/v1/users | 清晰、易缓存 | URL 变长 |
| Header | Accept: application/vnd.api.v2+json | URL 干净 | 难调试 |
| Query Param | /api/users?version=2 | 灵活 | 容易遗漏 |
推荐:URL Path(最常用、最易理解)
模式 7:速率限制(Rate Limiting)
// 滑动窗口示例(伪代码)
const WINDOW = 60 * 1000; // 1 分钟
const MAX_REQUESTS = 100;
function rateLimit(userId) {
const key = `rate:${userId}`;
const requests = redis.lrange(key, 0, -1);
// 清理过期
const now = Date.now();
redis.lrem(key, 0, `${now - WINDOW}`);
if (requests.length >= MAX_REQUESTS) {
throw new RateLimitError('请求过于频繁,请稍后重试', {
'X-RateLimit-Limit': MAX_REQUESTS,
'X-RateLimit-Remaining': 0,
'Retry-After': Math.ceil(WINDOW / 1000)
});
}
redis.lpush(key, now);
redis.expire(key, Math.ceil(WINDOW / 1000));
}
响应头:
X-RateLimit-Limit:总配额X-RateLimit-Remaining:剩余X-RateLimit-Reset:重置时间Retry-After:重试等待秒数
模式 8:JWT 认证
// Token 签发
function issueToken(user) {
return jwt.sign(
{ sub: user.id, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: '1h', issuer: 'myapp' }
);
}
// Token 验证
function verifyToken(token) {
try {
return jwt.verify(token, process.env.JWT_SECRET, {
issuer: 'myapp',
algorithms: ['HS256'] // 防止算法混淆攻击
});
} catch (e) {
throw new UnauthorizedError('Invalid token');
}
}
// 中间件
function authMiddleware(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Missing Authorization header' });
}
const token = authHeader.slice(7);
try {
req.user = verifyToken(token);
next();
} catch (e) {
return res.status(401).json({ error: 'Invalid token' });
}
}
关键安全实践:
- ✅ HTTPS only
- ✅ HttpOnly cookie(避免 XSS)
- ✅ 短 access token + 长 refresh token
- ✅ 算法白名单(防止
alg: none) - ✅ issuer + audience 校验
模式 9:数据库 Schema 设计原则
-- ✅ 软删除 + 审计字段
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'active',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ
);
CREATE INDEX idx_users_email ON users(email) WHERE deleted_at IS NULL;
CREATE INDEX idx_users_created_at ON users(created_at DESC);
审计字段:
created_at:创建时间updated_at:更新时间(trigger 自动维护)deleted_at:软删除(NULL = 未删除)
索引原则:
- WHERE 子句常用字段建索引
- 复合索引按选择性排序
- 部分索引:
WHERE deleted_at IS NULL
模式 10:缓存策略
Cache-Aside(最常用):
1. 读:先查 Redis,未命中则查 DB,写入 Redis
2. 写:更新 DB,删除 Redis(lazy invalidation)
3. TTL:根据数据更新频率
写穿透(Write-Through):
- 同步写 DB + Redis
- 强一致,但性能差
写回(Write-Behind):
- 异步写 DB
- 高性能,但可能丢失
Cache Stampede 防护:
- singleflight:同一 key 只查一次 DB
- 随机 TTL:避免雪崩
模式 11:消息队列
// Kafka 示例
async function publishEvent(topic, payload) {
await producer.send({
topic,
messages: [{
key: payload.id,
value: JSON.stringify(payload),
headers: {
'content-type': 'application/json',
'event-type': payload.type,
'trace-id': getTraceId()
}
}]
});
}
// Consumer:幂等消费
async function processMessage(message) {
const { id, type, data } = JSON.parse(message.value.toString());
// 幂等键:检查是否已处理
if (await redis.sismember('processed:events', id)) {
console.log(`Event ${id} already processed, skip`);
return;
}
await handleEvent(type, data);
// 标记已处理(成功后才标记)
await redis.sadd('processed:events', id);
}
幂等性关键:
- 业务 ID 作为幂等键
- 数据库唯一索引
- Redis SETNX 临时锁
- 处理成功后才提交 offset
模式 12:可观测性
日志(Logging):
- 结构化:JSON 格式
- 字段:timestamp、level、service、trace_id、message、context
- 工具:Loki / ELK / CloudWatch
指标(Metrics):
- RED:Rate(请求率)、Errors(错误率)、Duration(延迟)
- USE:Utilization、Saturation、Errors
- 工具:Prometheus + Grafana
追踪(Tracing):
- OpenTelemetry 标准
- 跨服务 trace_id 关联
- 工具:Jaeger / Zipkin / Tempo
四、6 大实战场景
场景 1:设计 SaaS API
用 backend-patterns 为我的 SaaS 设计完整 API:
- /api/v1/auth(注册、登录、刷新)
- /api/v1/users(CRUD)
- /api/v1/billing(订阅、发票)
- /api/v1/webhooks(事件回调)
- 错误格式、限流、JWT
场景 2:数据库 Schema 设计
设计一个电商系统的 schema:
- users / products / orders / payments / reviews
- 索引、约束、审计字段
- 软删除
场景 3:缓存架构
用 backend-patterns 设计 Redis 缓存策略:
- 哪些数据缓存
- TTL 设置
- 一致性保证
- 雪崩 / 穿透 / 击穿防护
场景 4:统一错误处理
设计错误处理中间件:
- 自定义错误类
- HTTP 状态码映射
- 用户友好提示
- 日志记录
- request_id 追踪
场景 5:异步任务系统
设计订单支付的异步流程:
- 任务队列选型(Kafka / RabbitMQ / BullMQ)
- 幂等性保证
- 重试策略(指数退避)
- 死信队列
场景 6:微服务拆分
我的单体应用想拆为微服务:
- 边界识别
- API 网关
- 服务间通信
- 数据一致性(Saga / 2PC)
- 可观测性
五、5 大反模式(必须避免)
反模式 1:上帝服务(God Service)
❌ 一个 service 10000+ 行
✅ 按业务边界拆分为多个 service
反模式 2:业务逻辑在 Controller
❌ controller 直接操作数据库
✅ controller 只做请求/响应转换,业务在 service 层
反模式 3:缺乏幂等性
❌ 重试导致重复扣款
✅ 每个操作有唯一 ID,重复请求返回原结果
反模式 4:同步调用链过长
❌ A → B → C → D → E(同步,5 秒延迟)
✅ 异步解耦,关键路径用消息队列
反模式 5:硬编码配置
❌ 数据库密码写在代码里
✅ 环境变量 + 密钥管理服务
六、安装
# Claude Code
/plugin marketplace add affaan-m/everything-claude-code
/plugin install backend-patterns@affaan-m
# 通用
npx skills add affaan-m/everything-claude-code --skill backend-patterns
七、6 条实战技巧
- RESTful 而非 RPC:URL 用资源,不用动词
- 错误格式统一:前端能稳定解析
- 状态码语义化:404 vs 400 vs 422 区别使用
- OpenAPI 规范:用 YAML 定义,自动生成文档
- HATEOAS:超媒体链接(高级场景)
- GraphQL 考虑:复杂关系用 GraphQL 更合适
参考资料
- affaan-m/everything-claude-code GitHub
- REST API 设计指南 - Microsoft
- JWT 最佳实践 - IETF RFC 7519
- OpenTelemetry 官方文档
- Redis 缓存策略
八、5 条反合理化
| 借口 | 反驳 |
|---|---|
| ”我们的 API 不规范也工作” | 等团队扩大、客户端多了,会出大事 |
| ”REST 太老派” | REST 仍是 API 主流,GraphQL 是补充不是替代 |
| ”状态码无所谓” | 5xx vs 4xx 影响监控告警策略 |
| ”错误格式不一致没事” | 前端要写 10 套解析,崩溃 |
| ”版本控制不用” | 不做版本控制 = 一次发布永远不能改 |
九、与其他 Skill 配合
| 配合 | 场景 |
|---|---|
| api-and-interface-design | 详细的 API 设计方法论 |
| postgres-patterns | 数据库设计 |
| clickhouse-io | OLAP 查询优化 |
| cloud-infrastructure-security | IAM、安全 |
| ci-cd-and-automation | 自动化部署 |
十、Q&A
Q: REST vs GraphQL 怎么选? A: 简单 CRUD 用 REST;复杂关系、客户端多端用 GraphQL。
Q: JWT 还是 Session? A: 移动 App 用 JWT(无状态),传统 Web 用 Session + Cookie。
Q: 错误信息返回堆栈吗?
A: 生产环境绝对不行。开发环境可以用 ?debug=true。
Q: API 网关必须吗? A: 微服务必需,单体可省。
Q: gRPC 何时用? A: 服务间高性能通信,移动 App 不适合(浏览器不支持)。
十一、总结
核心价值:
- 黑客马拉松冠军 10+ 个月实战沉淀
- 12 大模式覆盖完整后端架构
- 5 大反模式 + 6 大实战场景
适用人群:
- 所有后端工程师
- 全栈开发者
- 架构师
- Tech Lead
投入产出比:⭐⭐⭐⭐⭐(5/5)—— 必装。
快速安装
git clone https://github.com/affaan-m/everything-claude-code.git ln -s everything-claude-code/skills/backend-patterns ~/.claude/skills/backend-patterns