一、RESTful API 概述:什么是REST、RESTful API的核心原则、为什么选择RESTful
各位同学,咱们今天聊聊RESTful API。说实话,我刚入行那会儿,对REST也是一头雾水。那时候公司里大家都在说REST,但问起来每个人理解都不一样。后来我花了很长时间,踩了不少坑,才真正搞明白这东西到底是怎么回事。
嗯,咱们今天就把这事儿说透。
1.1 什么是REST?
REST,全称是Representational State Transfer,翻译过来叫「表述性状态转移」。这名字听着挺唬人,对吧?我第一次看到这个定义时,心里想的是:这什么鬼?
其实说白了,REST就是一种设计风格,不是协议也不是标准。它是由Roy Fielding博士在2000年他的博士论文中提出的。我记得当时读到那篇论文时,有种豁然开朗的感觉——原来我们平时写API的那些「好习惯」,人家早就总结成理论了。
REST的核心思想是:把服务器端的东西(资源)通过某种表现形式(JSON、XML等)暴露出来,客户端通过标准的HTTP方法来操作这些资源。
关键理解:REST不是技术,而是一种思维方式。它告诉你怎么组织你的API,怎么让客户端和服务端优雅地通信。
举个例子。你想想看,传统的RPC风格API长什么样?可能是这样的:
// RPC风格
POST /api/getUser
POST /api/createUser
POST /api/updateUser
POST /api/deleteUser
而REST风格呢?是这样的:
// REST风格
GET /api/users/{id} // 获取用户
POST /api/users // 创建用户
PUT /api/users/{id} // 更新用户
DELETE /api/users/{id} // 删除用户
看出来区别了吗?REST把操作对象(用户)和操作动作(GET/POST/PUT/DELETE)分开了。这就是REST最朴素的思想。
1.2 RESTful API的核心原则
我在项目中实践REST多年,总结下来,核心原则其实就六条。每条背后都有血泪教训,咱们一条条说。
原则一:资源导向
一切皆资源。用户、订单、商品、文章……这些都是资源。每个资源都有一个唯一的URI标识。
我曾经见过一个项目,API设计成这样的:
GET /api/getUserInfo
GET /api/getUserOrders
POST /api/updateUserAddress
这哪是REST啊,这分明就是RPC披了层HTTP的外衣。正确的做法是:
GET /api/users/{id}
GET /api/users/{id}/orders
PUT /api/users/{id}/address
资源就是名词,不要用动词。这是铁律。
原则二:统一接口
用标准的HTTP方法操作资源。我习惯这样对应:
| HTTP方法 | 操作 | 说明 |
|---|---|---|
| GET | 查询 | 获取资源,幂等,安全 |
| POST | 创建 | 新增资源,非幂等 |
| PUT | 全量更新 | 替换资源,幂等 |
| PATCH | 部分更新 | 修改部分字段,非幂等 |
| DELETE | 删除 | 移除资源,幂等 |
避坑指南:我曾经犯过一个错误,用POST做查询操作。结果前端同事调接口时,浏览器缓存完全用不上,每次都要重新请求。后来改成GET,性能提升了一大截。记住:查询用GET,别偷懒。
原则三:无状态
每个请求都是独立的,服务器不保存客户端的状态。说白了,你不能依赖「上一次请求」的信息来处理「这一次请求」。
为什么会这样?因为无状态才能水平扩展。你想想看,如果服务器要记住每个客户端的状态,那加机器的时候怎么办?状态同步就是个噩梦。
我参与过一个电商项目,早期没注意这个问题,把购物车信息存在了服务端Session里。结果每次扩容都要配置Session共享,折腾得够呛。后来改成客户端存Token,服务端只认Token不认人,扩容就简单多了。
原则四:可缓存
响应应该明确标识是否可缓存。这能大幅提升性能。
我个人习惯在响应头里加上Cache-Control和ETag。比如:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=3600
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
{
"id": 1,
"name": "张三",
"email": "zhangsan@example.com"
}
这样客户端就知道这个响应可以缓存1小时,而且可以通过ETag做条件请求,避免重复传输数据。
原则五:分层系统
客户端不知道它直接通信的是最终服务器还是中间代理。这种分层让架构更灵活。
嗯,这里要注意:分层虽然好,但会增加延迟。我一般建议在API网关层做缓存和限流,业务层专注业务逻辑,数据层专注数据存储。各司其职,互不干扰。
原则六:按需代码(可选)
服务器可以临时给客户端发送可执行代码,比如JavaScript。这个原则在实际中用得不多,我很少见到有团队这么搞。了解一下就行。
1.3 为什么选择RESTful?
说了这么多原则,你可能会问:我为什么要用REST?用RPC不也挺好的吗?
我个人的看法是:REST不是银弹,但在大多数场景下,它是最合适的选择。
原因有三:
- 简单直观:资源+HTTP方法,学习成本低。新来的同事看一眼就能上手。
- 生态成熟:各种框架、工具、客户端都对REST有很好的支持。PHP的Laravel、Symfony,前端的Axios、Fetch,都原生支持REST风格。
- 可扩展性强:无状态+可缓存+分层系统,让REST API天生适合分布式架构。
注意:REST不是万能的。如果你需要强一致性、复杂的事务操作,或者实时双向通信,REST可能不是最佳选择。这时候可以考虑GraphQL、gRPC或者WebSocket。
我记得有一次,团队里有个新人问我:「老师,我们是不是所有接口都要做成RESTful?」我的回答是:尽量遵守原则,但不要教条。比如批量操作、复杂查询,有时候用POST带查询参数反而更合适。REST是指导原则,不是法律条文。
好了,这一章咱们把REST的来龙去脉讲清楚了。下一章我会带你看看,在PHP里怎么搭建一个真正符合RESTful规范的API。到时候我会分享一些我在实际项目中的代码片段和踩坑经验,保证干货满满。
记住一句话:理解REST,不是记住那些原则,而是理解它背后的设计哲学——简单、统一、可扩展。