Skip to main content

API 设计

RESTful 规范

面试题:什么是 RESTful API?设计要点有哪些?

用 HTTP 方法表达对资源的操作,URL 表达资源(用名词复数,不用动词):

方法语义幂等示例
GET查询GET /usersGET /users/1
POST新建POST /users
PUT全量更新PUT /users/1
PATCH部分更新否(视实现)PATCH /users/1
DELETE删除DELETE /users/1
  • 常用状态码:200 成功、201 已创建、204 无内容、400 参数错误、401 未认证、403 无权限、404 不存在、409 冲突、429 限流、500 服务端错误、502/503 网关/服务不可用。
  • 版本控制/api/v1/users 或请求头 Accept: application/vnd.api.v1+json
  • 分页?page=1&pageSize=20(普通分页)或 ?cursor=xxx&limit=20(游标分页,适合大数据/无限滚动)。
  • 统一响应结构{ code, message, data },错误时返回明确的错误信息。

面试题:幂等是什么?哪些方法需要幂等?怎么保证 POST 幂等?

幂等 = 同一请求执行一次和多次效果相同。GET/PUT/DELETE 天然幂等,POST 不幂等。 保证 POST 幂等:客户端生成唯一幂等键(如 requestId),服务端用 Redis 记录已处理的 key,重复请求直接返回上次结果(防止重复下单/重复支付)。

GraphQL vs REST

-RESTGraphQL
端点多个 URL单一端点
取数可能 over/under-fetching按需取数,客户端决定字段
聚合多次请求一次请求聚合多资源
缓存HTTP 缓存天然支持需自行处理
成本简单学习成本、N+1、复杂度控制

GraphQL 适合字段需求多变、聚合多数据源的场景;简单 CRUD 用 REST 更轻。


实时通信

面试题:实时通信有哪些方案?怎么选?

方案方向原理场景
短轮询客户端 → 服务端定时发请求简单、实时性差
长轮询客户端 → 服务端请求挂起到有数据才返回兼容性好
SSE(Server-Sent Events)服务端 → 客户端(单向)基于 HTTP,text/event-stream 长连接消息推送、AI 流式输出、股价
WebSocket双向全双工HTTP 升级(Upgrade 头)后走 ws 协议聊天、协同编辑、游戏

WebSocket 要点

const { WebSocketServer } = require("ws");
const wss = new WebSocketServer({ port: 8080 });

wss.on("connection", (ws) => {
ws.on("message", (data) => {
// 广播给所有客户端
wss.clients.forEach((client) => client.send(data.toString()));
});
ws.send("connected");
});
  • 握手:以 HTTP 请求带 Upgrade: websocket 升级协议,之后全双工通信。
  • 心跳保活:定时 ping/pong 检测断线,配合断线重连。
  • 集群广播:多实例下用 Redis 发布订阅(pub/sub)做跨实例消息广播(如 socket.io-redis-adapter)。

更多见 网络/websocket


RPC 与消息队列(了解)

  • RPC:像调本地函数一样调远程服务,常见 gRPC(基于 HTTP/2 + Protobuf,性能高)。微服务内部通信常用。
  • 消息队列(MQ):RabbitMQ / Kafka,用于削峰填谷、异步解耦、最终一致性(如下单后异步发短信、扣库存)。
    • 要会答:如何保证消息不丢失(生产确认 + 持久化 + 消费 ack)、不重复消费(消费端幂等)、顺序消费。