04_综合项目
一套后端 API 对接 Vue 与 React 双前端,并用 Python、Go、Java 比较实现。
综合项目:双前端笔记服务
学习目标:用一份后端 API 契约分别实现 Vue 和 React 前端,并以 Python、Go、Java 三门语言对照后端实现。
1. 项目边界
构建一个仅用于学习的笔记服务,使用模拟用户和非敏感示例数据。功能包括登录、笔记列表、搜索、创建、编辑、删除和退出;每个用户只能操作自己的笔记。
<span style="color:#FF6347;font-weight:700;">验收重点:</span>先做一套稳定 API,再让 Vue 和 React 两个前端消费同一契约。后端先选熟悉的 Python 完成,随后用 Go、Java 复现关键接口,比较语言与框架差异。
2. API 与数据模型
核心表为 users 与 notes,详见 数据库设计与事务。建议最低接口:
| 路由 | 输入与输出 | 需要验证 |
|---|---|---|
POST /sessions |
登录信息 → 会话 | 错误凭证、限流 |
GET /notes |
分页条件 → 列表 | 只返回本人数据 |
POST /notes |
标题、正文 → 新笔记 | 空标题、重复请求 |
PATCH /notes/{id} |
变更字段 → 更新结果 | 版本冲突、越权 |
DELETE /notes/{id} |
ID → 204 | 不存在、越权 |
将接口字段和错误结构写成 OpenAPI 或等价契约,并为两套前端生成或维护一致的 TypeScript 类型。不要让 Vue 和 React 各自猜测状态码或字段含义。
3. 两套前端
- Vue 项目实践:Vue Router、状态/数据获取、表单与组件测试。
- React 项目实践:React Router、Hooks、服务端状态、表单与组件测试。
两套前端在功能和验收标准上保持一致;可以共享 API 契约与测试用例,但各自写页面和状态组织。公共逻辑抽取要有实际重复证据,不必为了“复用”提前制造复杂包结构。
4. 里程碑
- M0:契约——明确页面、表结构、状态码、权限和边界输入。
- M1:Python API——完成内存版,再接数据库与迁移。
- M2:Vue 与 React——两套前端都能跑通完整 CRUD 与错误反馈。
- M3:质量——单元、集成、API、组件和端到端测试覆盖关键流程。
- M4:发布——CI 构建、配置分离、日志、健康检查、备份与回滚说明。
- M5:语言对照——Go 和 Java 复现至少创建、列表、权限检查与数据库事务,并对比实现。
5. 完成标准
- 用户 A 无法读取或修改用户 B 的笔记;每个后端实现都有对应测试。
- 页面能处理加载、空列表、校验失败、网络失败和重复提交。
- 重启服务后数据仍在;迁移可以在干净数据库运行。
- CI 从干净环境执行通过;发布失败能按文档回滚。
- 对比三门语言的请求生命周期、并发模型、错误处理和依赖管理,而不仅是代码行数。
<div style="border-left:4px solid #4682B4;padding:0.55em 0.8em;margin:0.8em 0;color:#4682B4;"><strong>Tip:</strong>先让一个最小流程端到端成功,再逐步补安全、测试和性能。每个里程碑都应留下可运行命令与失败案例。</div>
6. 一份可落地的仓库结构
contracts/openapi.yaml # API 契约与错误码
backend/python/ # 首个完整后端
backend/go/ # 对照实现
backend/java/ # 对照实现
frontend/vue/ # Vue 版页面
frontend/react/ # React 版页面
tests/contract/ # 跨实现可复用的接口用例
docs/operations.md # 启动、迁移、备份和回滚
这是项目建议结构,不要求一开始就创建所有目录。先交付 GET /health、登录、列表和创建的纵向链路,再逐步扩展。两套前端共享字段与错误码,但各自实现路由、组件和状态组织;三套后端遵守同一 HTTP 契约,但不强求内部代码结构一致。
7. 契约示例:编辑冲突
客户端读取笔记得到 version: 3,提交 PATCH /notes/42 时带上预期版本 3;若另一客户端已更新到 4,服务端返回 409 与稳定的 version_conflict 错误码。前端应提示用户刷新或合并,不要静默覆盖他人更新。
{"code":"version_conflict","message":"笔记已更新,请刷新后重试"}
权限测试不能只看列表:用户 A 用用户 B 的 ID 请求详情、修改和删除都必须被拒绝。错误状态码可按契约选择 403 或隐藏为 404,但三个后端实现必须一致。
8. 每个里程碑如何验收
| 阶段 | 最小可验证证据 |
|---|---|
| <span style="color:#2E8B57;font-weight:600;">M0</span> | 契约文件、示例请求响应、权限矩阵 |
| <span style="color:#2E8B57;font-weight:600;">M1</span> | Python API 测试、数据库迁移、重启后数据仍在 |
| <span style="color:#2E8B57;font-weight:600;">M2</span> | Vue 与 React 均通过登录到创建笔记的 E2E |
| <span style="color:#2E8B57;font-weight:600;">M3</span> | 越权、重复请求、版本冲突和数据库故障测试 |
| <span style="color:#2E8B57;font-weight:600;">M4</span> | 干净环境构建、部署手册、回滚演练记录 |
| <span style="color:#2E8B57;font-weight:600;">M5</span> | Go、Java 契约测试通过及语言对照报告 |
完成后写一页复盘:最难的失败场景是什么、哪项测试先发现它、两套前端在状态与副作用管理上有何差异、三门后端语言在错误与并发模型上有何差异。这样项目成为可检验的知识,而不只是截图。