2. RESTful API 设计原则:资源命名规范、HTTP方法使用、状态码选择、版本控制策略

好,咱们直接进入正题。RESTful API 设计,说白了就是一套约定。大家按规矩办事,系统才能不乱。我在量化系统里摸爬滚打这么多年,见过太多因为 API 设计不规范导致的惨案。今天我把核心原则掰开揉碎了讲给你听。

2.1 资源命名规范:你的 URL 就是你的脸面

资源命名,是 API 设计的第一步。我个人的习惯是:用名词,不用动词;用复数,不用单数;用小写,不用大写;用连字符,不用下划线

为什么会这样?你想想看,REST 的核心是「资源」。因子、策略、回测结果,这些都是资源。操作资源的方法(增删改查)应该交给 HTTP 方法去表达,而不是塞进 URL 里。

核心原则:

  • 使用名词复数:/factors 而不是 /factor/getFactor
  • 层级关系用斜杠:/factors/{factor_id}/metrics
  • 查询参数用于过滤:/factors?status=active&page=1
  • 连字符分隔多单词:/factor-definitions 而不是 /factorDefinitions

我在项目中遇到过有人把 URL 写成 /getFactorDataByDate 的。嗯,这其实是个典型的反模式。你想想,如果每个接口都这么命名,那 API 文档会变成什么样子?一锅粥。

来看个正确的例子:

# 好的设计
GET    /factors                    # 获取因子列表
POST   /factors                    # 创建新因子
GET    /factors/{id}               # 获取单个因子
PUT    /factors/{id}               # 更新因子
DELETE /factors/{id}               # 删除因子
GET    /factors/{id}/returns       # 获取因子的收益序列

# 不好的设计
GET    /getAllFactors              # 动词混入
POST   /createNewFactor            # 同上
GET    /factor/delete?id=123       # 用 GET 做删除

2.2 HTTP 方法使用:别把 GET 当万能钥匙

HTTP 方法的选择,其实就四个字:各司其职

HTTP 方法 用途 幂等性 安全性 我踩过的坑
GET 查询资源 有人用 GET 传大量参数导致 URL 超长
POST 创建资源 重复提交导致数据重复
PUT 全量更新 漏传字段导致数据被清空
PATCH 部分更新 和 PUT 混用,语义不清
DELETE 删除资源 软删除和硬删除没区分

这里有个关键点:幂等性。说白了就是「调用一次和调用一百次,结果一样」。GET、PUT、DELETE 都是幂等的。POST 不是。为什么?你想想,你 POST 创建因子,点一次创建一个,点两次创建两个,这能一样吗?

我曾经犯过的错: 在量化回测系统中,用 POST 做「重新运行回测」。结果用户点了一下没反应(网络延迟),又点了一下。好家伙,两个回测任务同时跑,数据库里多了两份一模一样的结果。后来我改成 PUT 了,因为「重新运行」本质上是全量替换,幂等才是对的。

2.3 状态码选择:别只会用 200 和 500

状态码是 API 和调用方沟通的语言。我见过太多项目,不管成功失败,一律返回 200,然后在 body 里塞一个 {"code": 1, "msg": "error"}。这其实是在自废武功。

HTTP 状态码本身就是最好的错误描述,为什么不用?

我常用的状态码清单:

  • 200 OK:GET 成功、PUT 成功、PATCH 成功
  • 201 Created:POST 创建成功,记得返回 Location 头
  • 204 No Content:DELETE 成功,不需要返回 body
  • 400 Bad Request:参数校验失败,比如日期格式不对
  • 401 Unauthorized:没登录或 token 过期
  • 403 Forbidden:登录了但没权限
  • 404 Not Found:资源不存在
  • 409 Conflict:资源冲突,比如重复创建
  • 422 Unprocessable Entity:语义错误,比如因子公式语法不对
  • 429 Too Many Requests:限流了
  • 500 Internal Server Error:服务端炸了,别让用户看到堆栈

嗯,这里要注意:别把 400 和 422 搞混了。400 是「你发的东西我看不懂」,比如 JSON 格式错误。422 是「我看懂了,但逻辑上不对」,比如因子名称重复了。

2.4 版本控制策略:给 API 留条后路

版本控制,说白了就是「我改了接口,不能让你现有的代码崩掉」。我个人的建议是:用 URL 路径做版本控制,简单粗暴,一目了然

# 推荐做法:URL 路径版本
GET /api/v1/factors
GET /api/v2/factors

# 不推荐的做法:请求头版本
GET /factors
Headers: Accept: application/vnd.factorfactory.v1+json

为什么我推荐 URL 路径?因为直观。你打开浏览器,看 URL 就知道用的是哪个版本。请求头版本虽然「更 RESTful」,但调试起来太痛苦了。我在项目中用过一段时间请求头版本,结果每次联调都要跟前端说「你加个 Header 啊」,烦死了。

我的版本管理经验:

  • 小改动(加字段、加可选参数):不升版本,直接加,客户端忽略未知字段即可
  • 中改动(改字段名、改必选参数):升小版本,比如 v1.1,旧版本继续维护一段时间
  • 大改动(改接口语义、改数据结构):升大版本,比如 v2,旧版本给足迁移时间
  • 永远不要删除旧版本,除非你能确认 100% 没人用了

我曾经在 v1 版本上线半年后,直接把 v1 下线了。结果有个量化研究员写了个定时任务,每天凌晨跑,用的就是 v1。第二天早上他跑过来问我「数据怎么全错了?」。嗯,从那以后我再也不敢随便删旧版本了。

2.5 知识体系总览

下面这张图,是我对 RESTful API 设计原则的总结。你可以把它当成一张「检查清单」,每次设计新接口时对照着看一遍。

RESTful API 设计原则 资源命名规范 名词复数 小写+连字符 层级用斜杠 HTTP 方法使用 GET 查询 POST 创建 PUT/PATCH 更新 DELETE 删除 状态码选择 2xx 成功 4xx 客户端错 5xx 服务端错 版本控制策略 URL 路径版本 小改不升版 大改升大版 安全性与幂等性 GET 安全+幂等 PUT/DELETE 幂等 POST 不幂等 规范设计 → 减少沟通成本 → 提升系统稳定性

这张图把四个核心原则串起来了。你设计 API 时,可以拿它当个「思维导图」。每个分支都过一遍,基本不会出大问题。

一个小技巧: 设计 API 之前,先写一份「API 设计文档」,把资源、方法、状态码、版本号都定下来。让团队 review 一遍再动手写代码。我在团队里推行这个习惯后,返工率至少降了 60%。

好了,RESTful API 设计原则就讲到这里。记住:规范不是束缚,是解放。你按规矩来,调用方舒服,维护方也舒服。下次咱们聊具体的接口实现细节。


公众号:蓝海资料掘金营,微信deep3321