当你浏览Web网页时,从一个页面跳转到一个页面,再从另一个连接跳到另外一个页面,就是利用了超媒体的概念:把一个个把资源链接起来。要达到这个目的,就要求在表述格式里边加入链接来引导客户端。
在《RESTful Web Services》一书中,作者把这种具有链接的特性成为连通性。下面我用一个日常场景来解释:
假设你在图书馆查资料:
超媒体(Hypermedia)
就像网页的跳转链接,在 API 响应中通过url
字段或Link
响应头主动告诉客户端:
连通性(Connectedness)
让 API 像乐高积木一样自带拼接接口。例如 GitHub 的 API:
# 响应头中的分页导航
Link: ; rel="next"
# 响应体中的资源关联
{
"name": "alibaba",
"repos_url": "https://api.github.com/orgs/alibaba/repos"
}
对比传统误区
很多开发者过度设计"美观的URI"(如/users/123/orders/456
),但更好的做法是:
{
"order_id": 456,
"user": {
"id": 123,
"link": "/users/123" // 通过链接关联,而不是让客户端拼接URL
}
}
用一个餐厅点餐的开发流程来解释一下,配合简单代码示例:
// 假设你访问「餐厅菜单API」的初始入口
GET /api/restaurant
{
"name": "数字餐厅",
"_links": {
"菜单": "/api/menu", // ← 超链接:告诉你可以点这里看菜单
"我的订单": "/api/orders" // ← 超链接:告诉你可以点这里看订单
}
}
HTTP页面地址
GET: /api/menu
JSON代码
{
"items": [{
"id": 1,
"name": "汉堡",
"price": 30,
"_links": {
"加入购物车": "/api/cart/items" // ← 超链接:告诉你怎么操作
}
}],
"_links": {
"next_page": "/api/menu?page=2", // ← 分页超链接
"current_page": "/api/menu?page=1"
}
}
2. 下单后获得后续操作指引
HTTP页面地址
POST: /api/orders
{
"items": [{"id": 1, "quantity": 2}]
}
JSON代码
// 订单创建成功的响应
{
"order_id": "123",
"status": "待支付",
"_links": {
"支付": "/api/orders/123/payment", // ← 下一步该做什么
"取消订单": "/api/orders/123" // ← 其他可用操作
}
}
HTTP页面地址
POST: /api/orders/123/payment
JSON代码
{
"status": "支付成功",
"_links": {
"订单详情": "/api/orders/123", // ← 查看结果
"申请退款": "/api/orders/123/refund" // ← 新出现的可用操作
}
}
超媒体即导航地图
每个API响应都像网页一样自带链接,告诉你接下来能做什么(像地图上的路线指引)
应用状态引擎
客户端不需要提前知道所有接口地址,像跟着「流水线传送带」一样,每完成一步,服务端就告诉你下一步该去哪
对比传统API设计
传统方式[不推荐]:客户端需要硬编码所有接口地址(如知道支付接口必须是/orders/{id}/payment
)
超媒体方式[推荐]:客户端只需记住入口地址,后续全靠响应中的链接导航(服务端改接口路径也不影响客户端)
设计 API 时多思考:
Link
响应头或_links
字段暴露这些关系RESTful 的精髓不全是 CRUD 对应 HTTP 方法,也可以是让资源通过超媒体自己引导客户端完成状态流转。
让API自己告诉客户端「你现在能做什么」和「下一步该去哪」,就像游戏中的路径导航一样带着你前进,不需要自己考虑太多!