RESTful API 概念
资源、表述、无状态、统一接口四个核心概念,以及 Richardson 成熟度模型。
资源(Resource)
A resource is a named entity: a user, an order, a collection of orders. The URL only identifies it; operations are expressed by the HTTP method. /users/42 is the name of user 42 — reading, updating and deleting all reuse that name.
/users 集合资源(所有用户)
/users/42 单个资源(42 号用户)
/users/42/orders 子集合(42 号用户的订单)表述(Representation)
The server never ships the resource itself, only a representation of it at a point in time. One resource may have many representations — JSON, XML, CSV, HTML — and the client asks for one with Accept.
{
"id": 42,
"name": "Alice",
"email": "alice@example.com",
"_links": {
"self": {"href": "/users/42"},
"orders": {"href": "/users/42/orders"}
}
}无状态(Stateless)
The server keeps no client state between requests: each request carries its own identity (Authorization) and all parameters. Any instance can serve any request, so scaling is just adding machines; the cost is repeating that context every time.
有状态(不推荐):GET /next-page ← 依赖服务端记住「你上次看到第几页」
无状态(推荐): GET /users?page=3&size=20 ← 翻页信息由客户端携带统一接口(Uniform Interface)
- Resource identification — URLs name things, not actions
- Manipulation through representations — the client edits the JSON, then sends it back
- Self-descriptive messages — Content-Type and status codes carry the meaning
- HATEOAS — responses link to the next possible actions
Richardson 成熟度模型
| Level | What it does | Example |
|---|---|---|
| L0 | One endpoint, one verb (tunnel) | POST /api with an action field |
| L1 | Resources, but still one verb | POST /users/42 |
| L2 | HTTP verbs + status codes | GET/PUT/DELETE /users/42 |
| L3 | HATEOAS: hypermedia drives the client | Response carries _links |
资源(Resource)
资源是被命名的实体:一个用户、一张订单、一批订单。URL 只负责标识它,不描述操作。/users/42 是「42 号用户」这个名字,读它、改它、删它都由 HTTP 方法表达。
/users 集合资源(所有用户)
/users/42 单个资源(42 号用户)
/users/42/orders 子集合(42 号用户的订单)表述(Representation)
服务端从不直接传输「资源本身」,只传输它在某一时刻的表述。同一个资源可以有多种表述:JSON、XML、CSV、HTML。客户端用 Accept 声明想要哪种。
{
"id": 42,
"name": "Alice",
"email": "alice@example.com",
"_links": {
"self": {"href": "/users/42"},
"orders": {"href": "/users/42/orders"}
}
}无状态(Stateless)
服务端不在两次请求之间保存客户端状态。每个请求必须自带身份(如 Authorization 头)和全部参数。好处是任意一台实例都能处理任意请求,扩容只需加机器;代价是每次都要重复传输这些信息。
有状态(不推荐):GET /next-page ← 依赖服务端记住「你上次看到第几页」
无状态(推荐): GET /users?page=3&size=20 ← 翻页信息由客户端携带统一接口(Uniform Interface)
- 资源标识 —— URL 命名事物,不命名动作
- 通过表述操作 —— 客户端改 JSON 再提交
- 自描述消息 —— Content-Type 与状态码自带语义
- HATEOAS —— 响应里给出下一步可用动作的链接
Richardson 成熟度模型
| 级别 | 特征 | 例子 |
|---|---|---|
| L0 | 单端点、单方法(隧道式) | POST /api,body 里带 action |
| L1 | 有资源,但只用一种方法 | POST /users/42 |
| L2 | HTTP 方法 + 状态码 | GET/PUT/DELETE /users/42 |
| L3 | HATEOAS:超媒体驱动客户端 | 响应里带 _links |