RESTful API 设计那些事儿:别让你的接口变成一场灾难

2026-06-17 11 0

RESTful API 设计那些事儿:别让你的接口变成一场灾难

开门见山,我见过太多所谓的"RESTful API",实际上是RES​Tf​u​l​的灾难现场。URL 写得跟玩似的,状态码返回 200 表示"你密码错了",HTTP 方法?不存在的,全部 POST 走天下。

作为一个在后端泥潭里滚了好几年的程序员,今天来聊聊怎么设计一个让人想给你点star而不是提issue的API

一、URL设计:名字即契约,别随便起

URL是什么?是你的API的门牌号。一个好的URL应该:

  • 名词复数,资源为王:/users 而不是 /getUsers,不是 /user,也不是 /fetchUserById
  • 层级清晰,不要嵌套过深:/users/123/orders/456 这种两层还行,三层以上就该想想是不是设计有问题了
  • 不用动词,HTTP方法就是动词:GET /users 查用户,POST /users 创建用户,DELETE /users/123 删除用户
✅ GET    /articles        # 获取文章列表
✅ GET    /articles/42     # 获取单篇文章
✅ POST   /articles        # 创建文章
✅ PUT    /articles/42     # 更新文章
✅ DELETE /articles/42      # 删除文章

❌ GET  /getArticle?id=42
❌ POST /deleteArticle
❌ POST /createNewUser.php

二、状态码:别再返回200表示"服务器炸了"

这是重灾区。我见过最离谱的API,所有响应都返回200,然后在body里写 {"code": 500, "msg": "服务器内部错误"}。兄弟,你这是精神分裂式API设计

HTTP状态码是干嘛用的?是让调用方快速判断结果的,不是你随手填的数字。

200 OK           # 成功,别滥用
201 Created      # 创建资源成功
204 No Content   # 删除成功,无返回体

400 Bad Request  # 参数校验失败
401 Unauthorized # 没登录
403 Forbidden    # 登录了但没权限
404 Not Found    # 资源不存在

422 Unprocessable Entity  # 业务校验失败(比如余额不足)
429 Too Many Requests     # 请求太频繁了

500 Internal Server Error # 服务器真的炸了

记住:能用状态码表达的意思,别放body里。你又不是在写小说,不需要那么多细节描写。

三、错误响应:给开发者一条活路

当你的API报错时,请务必告诉调用者:发生了什么、错在哪、怎么改

{
  "error": {
    "code": "INVALID_PARAMETER",
    "message": "手机号格式不正确",
    "detail": {
      "field": "phone",
      "value": "12345",
      "hint": "请输入11位手机号"
    },
    "request_id": "req_abc123xyz"  // 这个很重要,排查问题全靠它
  }
}

request_id一定要有。当用户在群里骂你API烂的时候,有了这个ID你才能快速定位问题,而不是对着日志发呆。

四、分页:列表接口的灵魂

没有分页的列表接口,在数据量上来之后就是DoS攻击工具

GET /articles?page=1&per_page=20&sort=created_at&order=desc

响应应该长这样:

{
  "data": [...],
  "pagination": {
    "current_page": 1,
    "per_page": 20,
    "total": 342,
    "total_pages": 18,
    "has_next": true,
    "has_prev": false
  }
}

有人问:cursor分页和offset分页哪个好?简单说:数据会变动的场景用cursor(类似推特timeline),数据相对稳定的用offset。别无脑offset,数据量大了慢死你。

五、版本管理:让你的API活下去

API是要迭代的,但不能因为迭代就把现有用户全干掉。版本管理了解一下:

✅ GET /v1/users
✅ GET /v2/users
❌ GET /users/v1

放在URL路径里是最清晰的方式。有人喜欢放header里,说是"更优雅"——说实话,调试的时候你就知道多不优雅了。URL能直接试,谁用谁爽。

版本升级的原则:渐进式废弃,别一刀切。v1deprecated了,给个缓冲期,提前通知,别搞突然袭击。

六、安全:别让API变成大门敞开的保险箱

  • 认证用JWT或OAuth2,别自己发明轮子:什么md5(password + timestamp)签名,听着就不靠谱
  • 敏感操作要验权:读取和写入的权限要分开管理
  • 请求要限流:防止被人薅羊毛或者意外循环调用把你打挂
  • 输入要校验:SQL注入、XSS这些基础攻击,99%是因为懒
# 限流响应头示例
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 456
X-RateLimit-Reset: 1623945600

七、最容易踩的坑

1. 穷调用问题:一次获取用户信息需要调用 /user → /user/posts → /posts/123/comments,10次请求拿一页数据。解决方案:GraphQL或BFF聚合了解一下。

2. 过度设计:一个简单的CRUD,非要搞什么CQRS、事件溯源。兄弟,先跑起来,再考虑优化

3. 文档缺失或过时:代码和文档不一致,这不是,这是日常。推荐用OpenAPI/Swagger规范来写文档,代码即文档。

结语

API设计没有绝对的标准,但有一些底线:让调用者能猜到用法,让后来者能看懂逻辑,让运维能快速定位问题

下次设计API之前,先问自己三个问题:

  1. 这个URL我能不能直接丢给postman测试?
  2. 出错了,我有没有给足够的错误信息?
  3. 三个月后我自己看这段代码,会不会想骂人?

如果都是yes,那你大概率走在正确的路上。


记住:好的API是给开发者用的,也是给未来的自己用的。且写且珍惜。

相关文章

当AI开始整活:我和OpenClaw的日常
当AI开始整活:我和OpenClaw的日常
被一只小龙虾支配的日常:我用 OpenClaw 这几个月的真实体验
被一只小龙虾支配的日常:我用 OpenClaw 这几个月的真实体验
为什么你写的数据库连接池总在泄漏?我从Stack Overflow抄的答案居然是错的
一次SQL慢查询排查,让我差点被开除

发布评论