需求分析与设计:需求调研方法、系统边界划分、服务接口设计原则、RESTful API 设计规范
好,咱们进入第二章。需求分析与设计。
说实话,很多开发兄弟觉得这章“虚”,不如直接写代码实在。我以前也这么想。直到有一次,我花了两周写了一个服务,结果产品经理说“这不是我要的”。嗯,从那以后,我再也不敢跳过需求分析了。
这一章,咱们把需求调研、边界划分、接口设计这几个硬骨头啃下来。
2.1 需求调研方法:别让“我以为”毁了项目
需求调研,说白了就是搞清楚“到底要做什么”。我见过太多项目,开发闷头做,做完发现跟用户想要的差了十万八千里。
2.1.1 常见的调研方法
我个人习惯把这几种方法组合着用,效果最好:
| 方法 | 适用场景 | 我的经验 |
|---|---|---|
| 用户访谈 | 探索性需求,了解痛点 | 别问“你想要什么”,问“你现在怎么做的” |
| 问卷调查 | 大规模收集意见 | 问题别超过15个,否则没人填完 |
| 竞品分析 | 明确功能基线 | 别只抄功能,要分析人家为什么这么做 |
| 原型演示 | 验证需求理解是否一致 | 用Axure或Figma画个低保真,比写文档管用 |
| 数据分析 | 优化已有系统 | 埋点数据不会骗人,但要注意样本偏差 |
2.1.2 需求调研的避坑指南
我曾经在一个电商项目中踩过坑。业务方说“要一个促销功能”,我们直接开干。结果做出来,人家要的是“满减”,我们做的是“打折”。返工了两周。
所以,调研时一定要做到:
- 场景化追问:“什么情况下会用这个功能?”
- 量化指标:“每天大概处理多少笔?”
- 异常流程:“如果网络断了怎么办?”
2.2 系统边界划分:画好你的“一亩三分地”
系统边界,就是明确“你的服务管什么,不管什么”。我见过最乱的系统,就是所有逻辑都揉在一个服务里,改一个功能,重启整个系统。
2.2.1 划分原则
我一般遵循这几个原则:
- 业务职责单一:一个服务只做一件事,比如“订单服务”只管订单,“支付服务”只管支付。
- 数据独立:每个服务有自己的数据库,别共享一个库。否则耦合度太高。
- 变更频率一致:经常一起改的功能,放在一个服务里;很少改的,单独拆出来。
- 团队结构对齐:一个服务由一个团队负责,避免跨团队扯皮。
2.2.2 边界划分的常见模式
举个例子,一个典型的电商系统,我会这样划分:
2.3 服务接口设计原则:接口是契约,不是实现
接口设计,是服务之间通信的“合同”。合同写得好,大家合作愉快;合同写得烂,天天扯皮。
2.3.1 四大核心原则
| 原则 | 解释 | 反面案例 |
|---|---|---|
| 接口幂等性 | 同一个请求执行多次,结果一样 | 支付接口没做幂等,用户点了两次,扣了两笔钱 |
| 接口无状态 | 每次请求都包含所有必要信息 | 依赖 Session 存储用户信息,导致无法水平扩展 |
| 接口版本化 | 变更时保留旧版本,逐步迁移 | 直接修改接口,导致调用方全部报错 |
| 接口可测试性 | 接口逻辑清晰,容易构造测试用例 | 一个接口做了10件事,测试用例写不出来 |
idempotent_key(幂等键),服务端根据这个键去重。这样即使客户端重试,也不会产生重复数据。
2.4 RESTful API 设计规范:让接口像 URL 一样直观
RESTful API,说白了就是用 HTTP 协议的方法(GET、POST、PUT、DELETE)来操作资源。你想想看,如果接口设计得乱七八糟,前端同学会骂娘的。
2.4.1 资源命名规范
- 使用名词复数:
/users而不是/getUser - 层级关系用斜杠:
/users/123/orders - 不要用动词:
/orders/create是错的,应该用POST /orders - 查询参数用于过滤:
/orders?status=paid&page=1
2.4.2 HTTP 方法使用规范
| 方法 | 用途 | 是否幂等 | 请求体 |
|---|---|---|---|
| GET | 获取资源 | 是 | 无 |
| POST | 创建资源 | 否 | 有 |
| PUT | 全量更新资源 | 是 | 有 |
| PATCH | 部分更新资源 | 否 | 有 |
| DELETE | 删除资源 | 是 | 无 |
2.4.3 状态码使用规范
我见过很多项目,不管成功还是失败,一律返回 200。然后自己在 body 里写一个 code 字段。这种做法,说实话,很不专业。
正确的做法是:
- 200 OK:GET 成功、PUT 成功
- 201 Created:POST 创建成功
- 204 No Content:DELETE 成功
- 400 Bad Request:参数错误
- 401 Unauthorized:未认证
- 403 Forbidden:无权限
- 404 Not Found:资源不存在
- 500 Internal Server Error:服务器内部错误
2.4.4 一个完整的 RESTful API 示例
假设我们要设计一个“用户订单”相关的 API:
# 获取用户列表
GET /api/v1/users
# 获取单个用户
GET /api/v1/users/{user_id}
# 创建用户
POST /api/v1/users
Content-Type: application/json
{
"name": "张三",
"email": "zhangsan@example.com"
}
# 更新用户信息
PUT /api/v1/users/{user_id}
Content-Type: application/json
{
"name": "李四",
"email": "lisi@example.com"
}
# 删除用户
DELETE /api/v1/users/{user_id}
# 获取用户的订单列表
GET /api/v1/users/{user_id}/orders?status=paid&page=1&size=20
2.4.5 错误响应格式
我曾经在一个项目中,每个接口的错误格式都不一样。有的返回 {error: "xxx"},有的返回 {message: "xxx"}。前端同学对接的时候,快疯了。
所以,我建议统一错误响应格式:
{
"code": 40001,
"message": "参数校验失败",
"details": {
"field": "email",
"reason": "邮箱格式不正确"
}
}
这样,前端可以根据 code 做统一处理,根据 message 展示给用户,根据 details 定位具体问题。
好了,这一章的内容就这些。需求调研、边界划分、接口设计,这三件事做好了,后面的开发工作会顺畅很多。记住,磨刀不误砍柴工。