
fullstack-dev
热门全栈后端架构与前后端集成指南。 触发场景:构建全栈应用、配合前端开发 REST API、脚手架搭建后端服务、开发 Todo 应用、开发 CRUD 增删改查应用、开发实时应用、开发聊天应用、Express + React、Next.js API、Node.js 后端、Python 后端、Go 后端、设计服务层、实现错误处理、管理配置/鉴权、配置 API 客户端、实现身份验证流程、处理文件上传、添加实时功能(SSE/WebSocket)、生产环境加固。 不触发场景:纯前端 UI 工作、纯 CSS/样式调节、仅数据库 Schema 设计。
全栈后端架构与前后端集成指南。 触发场景:构建全栈应用、配合前端开发 REST API、脚手架搭建后端服务、开发 Todo 应用、开发 CRUD 增删改查应用、开发实时应用、开发聊天应用、Express + React、Next.js API、Node.js 后端、Python 后端、Go 后端、设计服务层、实现错误处理、管理配置/鉴权、配置 API 客户端、实现身份验证流程、处理文件上传、添加实时功能(SSE/WebSocket)、生产环境加固。 不触发场景:纯前端 UI 工作、纯 CSS/样式调节、仅数据库 Schema 设计。
全栈开发实践指南
强制工作流 — 务必按顺序执行以下步骤
触发本 Skill 时,在编写任何代码之前,必须严格遵循此工作流。
步骤 0:收集与明确需求
在搭建项目脚手架之前,先向用户确认(或从上下文推导):
- 技术栈:前后端使用的语言/框架(例如:Express + React、Django + Vue、Go + HTMX)
- 服务类型:仅 API 服务、全栈单体应用,还是微服务?
- 数据库:SQL(PostgreSQL、SQLite、MySQL)还是 NoSQL(MongoDB、Redis)?
- 集成方式:REST、GraphQL、tRPC 还是 gRPC?
- 实时通信:是否需要?如果需要,选择 SSE、WebSocket 还是轮询?
- 身份验证/鉴权:是否需要?如果需要,选择 JWT、Session、OAuth 还是第三方服务(Clerk、Auth.js)?
如果用户已在请求中指定上述内容,可跳过提问直接继续。
步骤 1:架构决策
根据需求,在写代码前先做出并明确以下决策:
| 决策项 | 选项 | 参考章节 |
|---|---|---|
| 项目结构 | 按功能模块组织(推荐)vs 按技术分层组织 | 第 1 节 |
| API 客户端方案 | 类型安全 fetch / React Query / tRPC / OpenAPI 代码生成 | 第 5 节 |
| 鉴权策略 | JWT + Refresh Token / Session / 第三方服务 | 第 6 节 |
| 实时通信方案 | 轮询 / SSE / WebSocket | 第 11 节 |
| 错误处理 | 类型化的错误层级结构 + 全局处理器 | 第 3 节 |
简要说明每个选择的理由(每个决策 1 句话即可)。
步骤 2:对照检查清单搭建脚手架
使用下方对应的检查清单。确保已勾选的项均已实现 — 切勿遗漏任何一项。
步骤 3:按照设计模式编码实现
参照本文档中的设计模式编写代码。在实现各个部分时,请随时参考对应的具体章节。
步骤 4:测试与验证
完成实现后,在声明完成前执行以下检查:
- 构建检查:确保前后端均能无错编译
# 后端 cd server && npm run build # 前端 cd client && npm run build - 启动与冒烟测试:启动服务器,验证关键 Endpoint 返回预期响应
# 启动服务器,然后测试 curl http://localhost:3000/health curl http://localhost:3000/api/<resource> - 集成检查:验证前端能够正常连接后端(CORS、API Base URL、鉴权流程)
- 实时通信检查(若适用):打开两个浏览器标签页,验证数据同步
如果有任何一项检查失败,先修复问题再继续。
步骤 5:交接总结
向用户提供简要总结:
- 已构建内容:已实现的功能和 Endpoint 列表
- 运行方式:启动前后端的准确命令
- 遗留项 / 后续计划:任何延后处理的项、已知局限或建议的改进
- 核心文件:列出用户需要了解的最重要文件
适用范围
在以下场景使用本 Skill:
- 构建全栈应用(后端 + 前端)
- 搭建新后端服务或 API 的脚手架
- 设计服务层与模块边界
- 实现数据库访问、缓存或后台任务
- 编写错误处理、日志记录或配置管理
- 评审后端代码的架构问题
- 进行生产环境加固
- 配置 API 客户端、鉴权流程、文件上传或实时功能
不适用于:
- 纯前端/UI 界面开发(请参考对应前端框架的文档)
- 缺少后端上下文的纯数据库 Schema 设计
快速入门 — 新后端服务检查清单
- [ ] 项目使用**按功能模块(feature-first)**的结构进行搭建
- [ ] 配置统一集中管理,环境变量在启动时完成校验(Fail-Fast 快速失败机制)
- [ ] 定义了类型化的错误层级结构(而非通用的
Error) - [ ] 配置了全局错误处理中间件
- [ ] 实现了带有 Request ID 传递的结构化 JSON 日志记录
- [ ] 数据库:配置好 Migration 迁移与连接池
- [ ] 所有 Endpoint 均完成输入校验(Zod / Pydantic / Go validator)
- [ ] 配置好身份验证中间件
- [ ] 配置好健康检查 Endpoint(
/health、/ready) - [ ] 处理了优雅停机(SIGTERM 信号)
- [ ] 配置了 CORS(明确指定 Origin,避免使用
*) - [ ] 配置了安全 HTTP 响应头(helmet 或同等工具)
- [ ] 提交了
.env.example(不含真实敏感信息)
快速入门 — 前后端集成检查清单
- [ ] 配置好 API 客户端(类型安全的 fetch 封装、React Query、tRPC 或 OpenAPI 生成代码)
- [ ] Base URL 从环境变量读取(禁止硬编码)
- [ ] 请求自动带上 Auth Token(拦截器 / 中间件)
- [ ] 错误处理 — API 错误映射为用户友好提示
- [ ] 处理好 Loading 加载状态(骨架屏/Spinner 菊花图,避免白屏)
- [ ] 跨边界的类型安全(共享类型、OpenAPI 或 tRPC)
- [ ] 生产环境 CORS 配置了明确的 Origin(禁止使用
*) - [ ] 实现了 Refresh Token 刷新流程(httpOnly Cookie + 401 无感重试)
快速导航
| 需求 | 跳转至 |
|---|---|
| 组织项目文件夹 | 1. 项目结构与分层 |
| 管理配置与敏感信息 | 2. 配置与环境变量 |
| 规范处理错误 | 3. 错误处理与容错 |
| 编写数据库代码 | 4. 数据库访问模式 |
| 从前端搭建 API 客户端 | 5. API 客户端模式 |
| 添加鉴权中间件 | 6. 身份验证与中间件 |
| 配置日志记录 | 7. 日志记录与可观测性 |
| 添加后台任务 | 8. 后台任务 |
| 实现缓存 | 9. 缓存模式 |
| 上传文件(预签名 URL、multipart) | 10. 文件上传模式 |
| 添加实时通信功能(SSE、WebSocket) | 11. 实时通信模式 |
| 在前端 UI 中处理 API 错误 | 12. 跨边界错误处理 |
| 生产环境加固 | 13. 生产环境加固 |
| 设计 API Endpoint | API 设计 |
| 设计数据库 Schema | 数据库 Schema |
| 鉴权流程(JWT、Refresh Token、Next.js SSR、RBAC) | references/auth-flow.md |
| CORS、环境变量、环境管理 | references/environment-management.md |
核心原则(7 条铁律)
1. ✅ 按“功能模块(FEATURE)”组织代码,而非按技术分层
2. ✅ Controller 层绝不包含任何业务逻辑
3. ✅ Service 层绝不导入 HTTP 请求/响应(req/res)类型
4. ✅ 所有配置均来自环境变量,在启动时校验,实现 Fail-Fast
5. ✅ 每个错误都有明确类型、日志记录并返回统一格式
6. ✅ 所有输入均在边界处校验 — 不信任客户端传来的任何数据
7. ✅ 使用带有 Request ID 的结构化 JSON 日志 — 杜绝 console.log
1. 项目结构与分层(关键)
按功能模块优先组织结构(Feature-First)
✅ 功能模块优先(Feature-first) ❌ 技术分层优先(Layer-first)
src/ src/
orders/ controllers/
order.controller.ts order.controller.ts
order.service.ts user.controller.ts
order.repository.ts services/
order.dto.ts order.service.ts
order.test.ts user.service.ts
users/ repositories/
user.controller.ts ...
user.service.ts
shared/
database/
middleware/
三层架构
Controller(HTTP 层) → Service(业务逻辑层) → Repository(数据访问层)
| 架构层 | 职责 | ❌ 严禁事项 |
|---|---|---|
| Controller | 解析请求、校验参数、调用 Service、格式化响应 | 编写业务逻辑、执行数据库查询 |
| Service | 处理业务规则、逻辑编排、事务管理 | 引入 HTTP 类型(req/res)、直接操作数据库 |
| Repository | 执行数据库查询、调用外部 API | 编写业务逻辑、引入 HTTP 类型 |
依赖注入(各语言实现示例)
TypeScript:
class OrderService {
constructor(
private readonly orderRepo: OrderRepository, // ✅ 注入接口
private readonly emailService: EmailService,
) {}
}
Python:
class OrderService:
def __init__(self, order_repo: OrderRepository, email_service: EmailService):
self.order_repo = order_repo # ✅ 注入依赖
self.email_service = email_service
Go:
type OrderService struct {
orderRepo OrderRepository // ✅ 接口
emailService EmailService
}
func NewOrderService(repo OrderRepository, email EmailService) *OrderService {
return &OrderService{orderRepo: repo, emailService: email}
}
2. 配置与环境变量(关键)
统一集中、带类型、Fail-Fast 快速失败
TypeScript:
const config = {
port: parseInt(process.env.PORT || '3000', 10),
database: { url: requiredEnv('DATABASE_URL'), poolSize: intEnv('DB_POOL_SIZE', 10) },
auth: { jwtSecret: requiredEnv('JWT_SECRET'), expiresIn: process.env.JWT_EXPIRES_IN || '1h' },
} as const;
function requiredEnv(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Missing required env var: ${name}`); // 快速失败
return value;
}
Python:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str # 必填 — 缺失则应用无法启动
jwt_secret: str # 必填
port: int = 3000 # 可选,带默认值
db_pool_size: int = 10
class Config:
env_file = ".env"
settings = Settings() # 若缺少 DATABASE_URL 则直接快速报错
规则
✅ 所有配置均通过环境变量管理(符合 Twelve-Factor 原则)
✅ 启动时校验必填变量 — 实现快速失败(Fail-Fast)
✅ 在配置层完成类型转换,不要在使用处零散转换
✅ 提交 .env.example 并附带样例/占位值
❌ 切勿硬编码敏感信息、URL 或凭据
❌ 切勿提交真实 .env 文件
❌ 切勿在代码各处散落 process.env / os.environ
3. 错误处理与容错(高)
类型化的错误层级结构
// 基类 (TypeScript)
class AppError extends Error {
constructor(
message: string,
public readonly code: string,
public readonly statusCode: number,
public readonly isOperational: boolean = true,
) { super(message); }
}
class NotFoundError extends AppError {
constructor(resource: string, id: string) {
super(`${resource} not found: ${id





