API设计原则:RESTful API设计规范、资源命名规则、HTTP方法选择、状态码使用规范、版本控制策略
各位同学好,我是你们的老朋友。今天我们来聊聊API设计原则。说实话,我见过太多API设计得乱七八糟的项目了。有的接口命名像天书,有的状态码乱用一气。嗯,这节课我就把我在工业界摸爬滚打多年的经验,一次性分享给你们。
核心观点:好的API设计,应该像一本清晰的使用说明书,而不是需要用户去猜的谜语。
一、RESTful API设计规范
RESTful,说白了就是一种设计风格,不是标准。我个人习惯把它理解为「面向资源的API设计」。什么意思呢?就是把所有东西都看成资源,然后用统一的方式去操作它们。
我在项目中遇到过最典型的反例:有人把删除电机参数的动作设计成 GET /deleteMotor?id=123。你想想看,这哪是RESTful?这分明是RPC(远程过程调用)的写法。
RESTful的核心约束有六点,我挑最重要的说:
- 客户端-服务器分离:前端只管展示,后端只管数据
- 无状态:每次请求都包含所有必要信息,服务器不存会话
- 可缓存:响应要明确是否可缓存,提升性能
- 统一接口:这是重点,下面详细讲
统一接口又包含四个子约束:资源标识、通过表述操作资源、自描述消息、超媒体作为应用状态引擎(HATEOAS)。最后这个HATEOAS,说实话,工业界用得不多,但前三个是必须遵守的。
二、资源命名规则
资源命名,我踩过的坑最多。曾经有个项目,接口命名五花八门:有驼峰的、有下划线的、还有中横线的。后来维护起来,那叫一个痛苦。
我总结了一套命名规范,你们直接拿去用:
| 规则 | 正确示例 | 错误示例 |
|---|---|---|
| 使用名词复数 | /motors |
/getMotor、/motorList |
| 使用小写字母 | /axis-config |
/AxisConfig |
| 单词间用中横线 | /servo-drivers |
/servo_drivers、/servoDrivers |
| 层级关系用斜杠 | /motors/123/parameters |
/motors/123/parameters(正确) |
| 避免过深嵌套 | /motors/123/parameters |
/motors/123/parameters/456/values |
我的小技巧:嵌套不要超过三层。如果超过三层,考虑用查询参数代替,比如 /motors/123/parameters?type=speed 而不是 /motors/123/parameters/speed。
三、HTTP方法选择
HTTP方法的选择,说白了就是「用什么动词去操作资源」。我见过有人把所有操作都用POST,理由是「简单」。嗯,简单是简单了,但API的语义全丢了。
标准用法如下:
| HTTP方法 | 操作 | 幂等 | 安全 | 示例 |
|---|---|---|---|---|
| GET | 查询资源 | 是 | 是 | GET /motors 获取电机列表 |
| POST | 创建资源 | 否 | 否 | POST /motors 创建新电机 |
| PUT | 全量更新 | 是 | 否 | PUT /motors/123 替换电机信息 |
| PATCH | 部分更新 | 否 | 否 | PATCH /motors/123 修改电机转速 |
| DELETE | 删除资源 | 是 | 否 | DELETE /motors/123 删除电机 |
注意:我曾经犯过一个错误,用POST去做查询操作。结果前端缓存策略完全失效,每次请求都打到后端,服务器压力山大。记住:查询用GET,别偷懒。
四、状态码使用规范
状态码,很多人觉得不就是200、404、500嘛。其实不然。HTTP状态码有五大类,每一类都有它的语义。用错了,客户端就会误解。
我常用的状态码就这几个:
- 200 OK:GET、PUT、PATCH成功时用
- 201 Created:POST创建资源成功时用,记得带上Location头
- 204 No Content:DELETE成功时用,或者更新操作不需要返回内容时
- 400 Bad Request:参数校验失败,客户端的问题
- 401 Unauthorized:没登录或token过期
- 403 Forbidden:登录了但没权限
- 404 Not Found:资源不存在
- 409 Conflict:资源冲突,比如重复创建
- 422 Unprocessable Entity:语义错误,比如JSON格式对但业务逻辑不对
- 500 Internal Server Error:服务器出错了,别乱用
避坑指南:我曾经把业务错误也用200返回,然后在body里放一个error code。结果前端每次都要先解析body,再判断有没有错误。后来改成用4xx状态码,前端直接走错误处理分支,代码简洁多了。
五、版本控制策略
版本控制,这是个老生常谈的问题。API一旦发布,就不能随便改了。但业务在变,需求在变,不改也不行。怎么办?版本控制。
我见过三种主流方式:
| 方式 | 示例 | 优点 | 缺点 |
|---|---|---|---|
| URL路径 | /v1/motors |
直观、容易路由 | URL变长、版本扩散 |
| 请求头 | Accept: application/vnd.myapi.v1+json |
URL干净、符合RESTful | 调试不方便、缓存困难 |
| 查询参数 | /motors?version=1 |
实现简单 | 容易被忽略、缓存key复杂 |
我个人习惯用URL路径方式。为什么?因为直观。你想想看,一个新人接手项目,看到 /v2/motors 和 /v1/motors,一眼就知道哪个是新版。用请求头的话,还得翻代码才知道版本号。
我的建议:版本号用整数,别用小数点。比如 v1、v2,别用 v1.1、v1.2。小版本更新应该向后兼容,不需要改版本号。只有不兼容的变更才需要升大版本。
知识体系总览
下面这张图,是我自己画的API设计原则知识体系。你们可以保存下来,设计API时对照着看。
好了,以上就是API设计原则的核心内容。从RESTful规范到资源命名,从HTTP方法到状态码,再到版本控制,每一步都有讲究。记住:好的API设计,是让调用者感到舒服,而不是让实现者感到方便。
最后送大家一句话:API设计不是写代码,是定契约。契约清晰,合作愉快;契约模糊,后患无穷。