写一个能用的 API 很简单,写一个让调用方觉得顺手的 API 却是一门学问。一个设计良好的 RESTful API 能让前后端协作效率翻倍,而糟糕的 API 则让团队陷入无尽的沟通噩梦。

URI 命名原则

资源用名词复数,不用动词:

❌ 不好 ✅ 好
/getUsers /users
/createOrder /orders
/deleteUser?id=1 /users/1

HTTP 方法本身就表达了动作——GET(获取)、POST(创建)、PUT/PATCH(更新)、DELETE(删除)。不要在 URI 上再重复一遍。

HTTP 方法语义

方法 语义 幂等 示例
GET 获取资源 GET /users/123
POST 创建资源 POST /users
PUT 全量替换 PUT /users/123
PATCH 部分更新 PATCH /users/123
DELETE 删除资源 DELETE /users/123

状态码的正确用法

状态码 含义 使用场景
200 OK 成功 GET、PUT、PATCH
201 Created 已创建 POST
204 No Content 成功无返回 DELETE
400 Bad Request 格式错误 参数校验失败
401 Unauthorized 未认证 Token 缺失
403 Forbidden 无权限 权限不足
404 Not Found 不存在 记录不存在
409 Conflict 冲突 重复创建
422 Unprocessable 语义错误 业务逻辑不通过
500 Internal Error 服务器错误 未预期异常

常见误区: 把所有错误都返回 400。应该区分请求格式错误(400)、认证失败(401)、业务逻辑错误(422)和服务器错误(500)。

错误响应体标准

1
2
3
4
5
6
7
8
9
{
"error": {
"code": "VALIDATION_ERROR",
"message": "用户名已存在",
"details": [
{ "field": "username", "reason": "duplicate" }
]
}
}

统一错误格式让调用方用一个分支就能处理所有异常——远比每个接口返回不同的错误结构要友好。

分页与过滤标准

1
GET /users?page=2&limit=20&sort=-created_at&q=search&status=active

返回体包含分页元数据:

1
2
3
4
5
6
7
8
9
{
"data": [ /* ... */ ],
"meta": {
"page": 2,
"limit": 20,
"total": 156,
"totalPages": 8
}
}

API 版本管理

三种主流方案:

  1. URI 版本(最直观):/v1/users/v2/users
  2. 请求头版本Accept: application/vnd.myapp.v2+json
  3. 查询参数版本/users?version=2

对于公开 API,URI 版本最简单粗暴、调用方最容易理解。

总结

好的 API 设计不依赖天才的直觉,而是依赖一套清晰的规范。URI 命名有规律、状态码语义准确、错误格式统一、分页过滤规范——这些看似基础的东西积累起来,就是团队协作的超级润滑剂。