什么是 RESTful API?凭什么能流行 20 多年?

你是小阿巴,刚入职的后端程序员,负责给前端的阿花提供 API 接口。

结果一周后,你被阿花揍得鼻青脸肿。

阿花:你是我这辈子见过接口写的最烂的程序员!

你一脸委屈找到号称 "开发之狗" 的鱼皮诉苦:接口不是能跑就行吗?

鱼皮嘲笑道:小阿巴,你必须得学学 RESTful API 了。

你挠挠头:阿巴阿巴,什么玩意,没听说过!

⭐️ 推荐观看视频版,动画更生动:bilibili.com/video/BV1WF...

什么是 RESTful API?

鱼皮:首先,REST 的全称是 REpresentational State Transfer,翻译过来叫 "表现层状态转移"。

你一脸懵:鱼皮 gie gie,能说人话吗?我是傻子,听不太懂。

鱼皮:别急,我给你拆开来讲,保证你理解。

RE(Representational) 表现层,是指 资源(Resource) 的表现形式。

你好奇了:什么是资源?

鱼皮:资源就是 你想要操作的数据对象

比如用户、商品、文章,这些都是资源。用户列表是一个资源,某个具体的用户也是一个资源。

表现层是指资源呈现出来的具体格式,比如同一个用户资源,可以用 JSON 格式返回给客户端,也可以用 XML 格式返回,这就是不同的 "表现形式"。

S(State) 是指 "状态"。

你:啥是状态?

鱼皮:比如你登录网站后,服务器会在内存中记住 "你是谁",之后在网站上操作就不用再次登录了,这就是 有状态

无状态(Stateless) 呢,就是服务器不记录客户端的任何信息,每次请求都是独立的。

你:哦哦哦,就像一个人去餐厅吃饭,服务员不记得他上次点了什么,每次都要重新点单,这就是无状态。

反过来,服务员记得他爱吃鱼皮,这就是有状态。

鱼皮:没错,接下来是 T(Transfer) 转移。

要注意,转移是 双向 的:

1)当你用 GET 请求时,服务器把资源的状态(比如用户信息的 JSON 数据)转移给客户端。

2)当你用 POST/PUT 请求时,客户端把资源的新状态(比如新用户的信息)转移给服务器,从而改变服务器上资源的状态。

组合起来,REST(Representational State Transfer) 是一种 软件架构风格,让客户端和服务器通过统一的接口,以无状态的方式,互相传递资源的表现层数据(比如 JSON),来查询或者变更资源状态。

ful 是个后缀,就像 powerful(充满力量的)一样,表示 "充满...特性的"。

因此,RESTful API 是指符合 REST 架构风格的 API,也就是遵循 REST 原则设计出来的接口。

注意,它 不是协议、不是标准、不是强制规范,只是一种建议的设计风格。你可以遵循,也可以不遵循。

你挠了挠头:说了一大堆,RESTful API 到底长啥样啊?

鱼皮:举个例子,比如你要做个用户管理系统,对用户信息进行增删改查,用 RESTful 风格的 API 就长这样:

bash 复制代码
GET /users/123       获取 ID 为 123 的用户
POST /users         创建新用户
PUT /users/123       更新用户 123
DELETE /users/123   删除用户 123

你眼前一亮:哇,比我写的整齐多了!

快带我学一下 RESTful 的写法吧,我要让前端阿花刮目相看!

RESTful API 写法

鱼皮:好,很有志气!接下来我会带你一步步构造一个完整的 RESTful API。分为两部分,客户端发送请求服务端给出响应

客户端请求

第一步:确定资源

资源用 URI(统一资源标识符)来表示。核心原则是:用名词来表示资源,不用动词

具体来说,推荐用名词复数表示资源集合 ,比如 /users 表示用户列表、/products 表示商品列表。

如果要操作 具体某个资源,就加上 ID ,比如 /users/123 表示 ID 为 123 的用户。

资源还 支持嵌套 ,比如 /users/123/orders 表示用户 123 的所有订单。

你想了想:那还可以更深层级么?比如 /users/123/orders/456 表示用户 123 的订单 456。

鱼皮点点头:你的理解完全正确,但不建议嵌套层级太深。

第二步:选择动作

确定了资源后,接下来要选择 动作,也就是你想怎么处理这个资源。

RESTful API 主要通过不同的 HTTP 方法来表示增删改查操作:

1)GET:查询资源

  • GET /users 查询所有用户
  • GET /users/123 查询 ID 为 123 的用户

2)POST:创建资源

  • POST /users 创建新用户

3)PUT:完整更新资源,需要提供资源的所有字段,多次执行结果相同(幂等性)

  • PUT /users/123 完整更新用户 123

4)PATCH:部分更新资源,通常用于更精细的操作

  • PATCH /users/123 只更新用户 123 的某些字段

5)DELETE:删除资源

  • DELETE /users/123 删除用户 123

鱼皮:到这里,一个基本的 RESTful API 请求就构造完成了。

你:就这么简单?我不满足,还有更高级的写法吗?

鱼皮:当然~

第三步:添加查询条件(可选)

有时候我们需要更精确地筛选数据,这时候可以加查询参数,比如:

  • 分页:/users?page=2&limit=10 查询第 2 页,每页 10 条用户数据
  • 过滤:/users?gender=male&age=25 查询性别为男、年龄 25 的用户
  • 排序:/users?sort=created_at&order=desc 按创建时间倒序排列用户

你:等等,这查询参数跟 RESTful 有啥关系?正常的请求不都是这么写吗?

鱼皮:确实,查询参数本身不是 RESTful 特有的。但 RESTful 风格强调 把筛选、排序、分页这些操作,都通过 URL 参数来表达

而不是在请求体里传一堆复杂的 JSON 对象:

这样一来,URL 更清晰,而且浏览器、CDN、代理服务器都能直接根据 URL 来缓存响应结果。比如 /users?page=1/users?page=2 是两个不同的 URL,可以分别缓存。但如果把参数放在请求体里,URL 都是 /users,缓存就没法区分了。

第四步:版本控制(可选)

随着业务发展,接口可能需要升级。为了不影响老用户,可以在 URI 中标明版本:

  • /v1/users 第一版用户接口
  • /v2/users 第二版用户接口

这样,老用户继续用 v1,新用户用 v2,互不影响。

第五步:保持无状态

此外,还记得我们前面讲 REST 里的 ST(State Transfer) 吗?

RESTful 的核心原则之一是 无状态(Stateless) ,客户端每次请求必须包含所有必要信息,服务器不记录客户端状态。

比如用户登录后,不是让服务器记住 "你已经登录了",而是每次请求都要带上身份凭证(Token),像这样:

sql 复制代码
GET /orders
Header: Authorization: Bearer xxx

这么做的好处是,服务器不用记录谁登录了、谁没登录,每个请求都是独立的。这样一来,你想加多少台服务器都行,任何一台都能处理请求,轻松实现负载均衡和横向扩展。

你点头如捣蒜:怪不得我调用 AI 大模型 API 的时候,就要传这个 Token!

服务端响应

鱼皮:讲完客户端请求,再来看服务器收到请求后,该怎么响应?

主要注意 2 点:

1、统一响应格式

目前大多数 RESTful API 基本都用 JSON 格式,因为轻量、容易解析。

perl 复制代码
{
 "id": 123,
 "name": "小阿巴",
 "email": "aba@codefather.cn"
}

但这并不是强制的,也可以用 XML、HTML 等格式。

2、返回合适的 HTTP 状态码

响应要带上合适的状态码,让客户端一眼看懂发生了什么。

HTTP 状态码有很多,大体可以分为 5 类:

  • 1xx 系列:信息提示(用得少,了解即可)

  • 2xx 系列:成功

    • 200 OK:请求成功,正常返回数据(用于 GET、PUT、PATCH)
  • 3xx 系列:重定向

    • 301 Moved Permanently:资源永久移动到新位置
    • 302 Found:资源临时移动
  • 4xx 系列:客户端错误

    • 400 Bad Request:请求参数格式错误
    • 401 Unauthorized:未验证身份,需要登录
    • 403 Forbidden:已认证但没有权限访问
    • 404 Not Found:资源不存在
    • 405 Method Not Allowed:请求方法不被允许
  • 5xx 系列:服务器错误

    • 500 Internal Server Error:服务器内部错误
    • 502 Bad Gateway:网关错误
    • 503 Service Unavailable:服务暂时不可用
    • 504 Gateway Timeout:网关超时

你恍然大悟:懂了,以后前端看到 500,就知道是我后端的锅;看到 400,就知道是她自己传参传错了。谁也别想甩锅!

鱼皮点点头:不错,以上这些,就是 RESTful API 的基本写法。你学会了吗?

你:学废了,学废了!

鱼皮:那我来考考你,下面哪个是标准的 RESTful API?

  • A. GET /getUsers
  • B. GET /user/list
  • C. POST /users/query
  • D. GET /users/delete/123

你开心地怪叫起来:阿巴,肯定是 C 啊!

鱼皮:错,4 个全都不标准

  • A 用了动词 getUsers
  • B 用了单数 user 和动词 list
  • C 用 POST 查询,还带了动词 query
  • D 用 GET 删除,还带了动词 delete

你掉了根头发:原来这么严格!

等等,你说 RESTful 不能用动词,但有些操作不是标准的增删改查啊,比如用户要支付订单,该怎么设计接口呢?是要用 POST /orders/123/pay

鱼皮摇头:你已经很努力了,但 pay 是动词。更标准的设计是把 "支付" 行为看作 创建 一个支付记录,用名词而不是动词。

bash 复制代码
POST /orders/123/payments

比如这个请求,表示为订单 123 创建一笔支付记录。

你又掉了根头发:妙啊,怪不得说英语对学编程有帮助呢,我悟了,我悟了!

RESTful 的六大约束

鱼皮:不错,学到这里你已经掌握了 RESTful 的 80%,能够实际应用了。接下来的知识,你只需简单了解一下,就能拿去和面试官吹牛皮了。

比如很多同学都不知道,RESTful 其实有 6 个约束条件:

  1. Client-Server(客户端-服务器分离):前后端各干各的活,前端负责展示,后端负责数据处理,互不干扰。
  2. Stateless(无状态):每次请求都是独立的,服务器不保存客户端的会话信息,所有必要信息都在请求中携带。
  3. Cacheable(可缓存):服务器的响应可以被标记为可缓存或不可缓存,客户端可以重用缓存数据,减少服务器压力,提升性能。
  4. Layered System(分层系统):客户端不需要知道直接连的是服务器还是中间层,系统可以灵活地加代理、网关、负载均衡器等。
  5. Uniform Interface(统一接口):所有资源都通过统一的接口访问,降低理解成本,提高可维护性。
  6. Code-On-Demand(按需代码):可选项,服务器可以返回可执行代码(比如 JavaScript)给客户端执行,但实际工作中很少用。

你直接听懵了:阿巴阿巴,这么多约束,我必须全遵守吗?

鱼皮:可以不用,RESTful 只是一种 API 的 建议风格 。在实际工作中,很少有 API 能完美符合所有约束,大家可以灵活调整,甚至什么接口都用 POST + 动词 一把梭。只要团队达成一致、用得舒服就行。

就像刚才那个支付订单的例子,POST /orders/123/payments 虽然符合 RESTful 规范,但有同学会觉得 POST /orders/123/pay 更直观易懂,也没问题。

不过现阶段,我建议你先养成遵循 RESTful 的好习惯,等积累了经验,再根据实际情况灵活调整。

怎么快速实现 RESTful API?

你:呜呜,但我只是个小阿巴,背不下来这些写法,我怕自己写着写着就不规范了,怎么办啊?

鱼皮:别担心,有很多方法可以帮你快速实现和检查 RESTful API。

1、使用开发框架

几乎所有主流开发框架都支持 RESTful API 的开发,它们能帮你自动处理很多细节,比如:

  • Java 的 Spring Boot:通过 @GetMapping("/users")@PostMapping("/users") 等注解,你只需要写一行代码就能定义符合 RESTful 风格的路由。框架会自动把对象转成 JSON、设置正确的 HTTP 状态码,你都不用操心。
  • Python 的 Django REST Framework:你只需要定义一个数据模型(比如 User 类),框架就能自动生成 GET /usersPOST /usersPUT /users/123DELETE /users/123 这一整套 RESTful 接口,大幅减少代码量。
  • Go 的 Gin :专门为 RESTful API 设计,语法非常简洁。比如 router.GET("/users/:id", getUser) 就能绑定一个 GET 请求,自动从 URL 中提取 ID 参数,还能通过路由分组把 /api/v1/users/api/v2/users 轻松分开管理。

这些框架虽然不强制你遵循 RESTful,但用它们的特性,开发起来既轻松又规范,帮你省掉大量重复代码。

2、使用 IDE 插件

比如 IDEA 的 RESTful Toolkit 插件,可以快速查看和测试接口。

还有 VSCode 的 REST Client 插件,可以直接在编辑器里测试接口。

3、利用 AI 生成

RESTful 有明确的设计规范,而 AI 最擅长处理这种有章可循的东西!

比如直接让 Cursor 帮你用 Spring Boot 写一个用户管理的 RESTful API:

你只需要阿巴阿巴几下,它就能生成规范的代码。

4、生成接口文档

写完接口后,还可以用 Swagger 这类工具自动生成漂亮的接口文档,直接甩给前端,对方一看就懂,还能在线测试接口,省去大量沟通成本。

你笑得像个孩子:这么一看,RESTful API 不仅让接口规范统一,还能提高开发效率,降低团队沟通成本,前后端都舒服!爽爽爽!

鱼皮点点头:没错,这也是为什么 RESTful 能成为业界主流的原因。

你:学会了学会了,我这就去重构所有接口,让前端阿花刮目相看!

结尾

一周后,你把所有接口重构成了 RESTful 风格。

前端阿花打开新的接口文档,眼睛亮了:小阿巴,你居然开窍了?!

你得意地笑了:那是,我可是学过 RESTful 的男人~ 阿花,晚上要不要一起?

阿花朝你吐了口唾沫:呸,你只不过学了一种 API 风格就得意洋洋。阿坤哥哥不仅精通 RESTful,还能手撕 GraphQL 和 gRPC 呢,你行么?

你难受得不行:啥啥啥,这都是啥啊...... 鱼皮 gie gie 快来救我!

更多

💻 编程学习交流:编程导航 📃 简历快速制作:老鱼简历 ✏️ 面试刷题神器:面试鸭

相关推荐
+VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue健身房管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
用户729429432232 小时前
Shiro框架工作原理与实践精讲
后端
用户729429432232 小时前
uni-app实战在线教育类app开发
后端
用户729429432232 小时前
数据中心虚拟化之KVM虚拟化基本部署视频课程
后端
www_stdio2 小时前
让大语言模型拥有“记忆”:多轮对话与 LangChain 实践指南
前端·langchain·llm
inferno2 小时前
JavaScript 基础
开发语言·前端·javascript
幌才_loong2 小时前
深入解析 C# async/await 执行原理:从语法糖到状态机
后端·.net
cindershade2 小时前
Intersection Observer 的实战方案
前端