REST API 面试题考察的是你能否设计出别人用起来不会踩坑的接口。下面整理了 20 道题及参考答案,从基础概念到后端和全栈面试中常被追问的设计细节都有覆盖。关于 HTTP 方法的规则,我们参考了 RFC 9110 中的定义。
基础
1. 什么是 REST?
REST 是一种面向网络系统的架构风格,核心是用 URL 标识资源,用一小组标准操作来操作资源,并用 JSON 等表示形式来描述资源。REST API 是无状态的:每个请求都自带服务器处理它所需的信息,因此任何一台服务器都能处理任何一个请求。
2. 在实际中,什么样的 API 才算“RESTful”?
- URL 中用名词表示资源,比如 /orders/42,而不是 /getOrder 这类动词
- 用标准 HTTP 方法表示操作
- 使用有意义的状状态码
- 请求无状态
- 表示形式和错误结构保持一致
面试时可以说,现实中很少有 API 完全遵循 REST 的每一条约束,你的目标是让行为可预测。
3. 主要的 HTTP 方法分别用来做什么?
| 方法 | 用途 | 安全 | 幂等 |
|---|---|---|---|
| GET | 读取资源 | 是 | 是 |
| POST | 创建资源或触发操作 | 否 | 否 |
| PUT | 替换资源 | 否 | 是 |
| PATCH | 部分更新资源 | 否 | 不保证 |
| DELETE | 删除资源 | 否 | 是 |
“安全”指请求不会改变服务器状态。“幂等”指发送多次和发送一次的效果相同。
4. 幂等是什么意思,为什么重要?
如果重复发送某个请求,最终状态和只发一次是一样的。它之所以重要,是因为网络会出故障。如果客户端对 PUT 请求超时了,它可以放心重试。而创建订单的 POST 可能会创建两笔订单,所以 API 通常会接受幂等键:客户端发送一个唯一键,服务器如果再次看到这个键,就返回之前存下的结果。
5. PUT 还是 PATCH?
PUT 用你发送的请求体替换整个资源,你没写的字段会被清空或重置。PATCH 只修改你发送的字段。小范围更新用 PATCH,当客户端持有完整表示时用 PUT。
状态码与错误
6. 你会用哪些状态码,分别在什么时候用?
| 状态码 | 用途 |
|---|---|
| 200 | 成功,并返回响应体 |
| 201 | 已创建,并通过 Location 头指向新资源 |
| 204 | 成功但无响应体,比如删除操作 |
| 400 | 请求格式错误或无效 |
| 401 | 未认证 |
| 403 | 已认证但无权限 |
| 404 | 资源未找到 |
| 409 | 与当前状态冲突,比如重复 |
| 422 | 格式正确但校验失败 |
| 429 | 请求过多 |
| 500 | 服务器错误 |
| 503 | 服务不可用 |
一个常见的追问是 401 和 403 的区别。401 的意思是“我不知道你是谁”,403 的意思是“我知道你是谁,但你不能做这件事”。
7. API 应该如何返回错误?
使用正确的状态码和一致的响应体。好的错误响应体包含稳定的机器可读错误码、给人看的提示信息,如果是校验错误,还要说明哪些字段没通过。不要把堆栈信息或内部细节泄露给客户端。
8. 你如何处理校验?
即使客户端也做了校验,服务器端仍然要校验。尽量一次性返回所有问题,避免用户一个一个地改,并且统一使用 400 或 422。
设计
9. 如何为关联关系设计 URL?
当子资源只在父资源下才有意义时,就嵌套,比如 /users/7/orders。嵌套层级要浅。超过一到两层,就直接暴露子资源,比如 /orders/42,再用查询参数过滤,比如 /orders?userId=7。
10. 如何对列表做分页?
| 方式 | 工作原理 | 权衡 |
|---|---|---|
| 偏移量和限制 | ?offset=40&limit=20 | 简单,但在大表上慢,且数据变化时可能跳过或重复条目 |
| 游标 | ?after=<token>&limit=20 | 稳定且快,但没法跳到第 50 页 |
| 页码 | ?page=3 | 对 UI 友好,但有和偏移量一样的问题 |
对于数据量大或变化快的场景,游标分页通常是首选。返回下一个游标,以及是否还有更多结果的提示。
11. 如何做过滤和排序?
用查询参数,比如 ?status=open&sort=-created_at。把你允许的字段列入白名单,避免暴露未建索引或敏感的列,同时保持查询快速。
12. 如何对 API 做版本管理?
| 方式 | 示例 | 说明 |
|---|---|---|
| 放在 URL 里 | /v2/orders | 简单、直观 |
| 放在请求头里 | Accept: application/vnd.example.v2+json | URL 更干净,但在浏览器里更难测试 |
| 查询参数 | ?version=2 | 简单,但容易忘 |
无论选哪种,都要避免在同一版本内做破坏性变更。新增字段通常是安全的,删除或重命名字段则不是。
13. 什么是 HATEOAS?
响应里包含指向相关操作的链接,这样客户端就能发现接下来能做什么,而不用硬编码 URL。它是 REST 定义的一部分,但很少有 API 完整实现它。你可以说你知道它,而且大多数团队改用文档和 OpenAPI 描述。
安全与性能
14. 如何对 API 做认证?
常见选择有:用于简单服务器到服务器调用的 API 密钥、JSON Web Token 之类的持有者令牌,以及当用户授权某个应用访问其数据时使用的 OAuth 2.0。始终使用 HTTPS。把密钥排除在 URL 之外,因为 URL 会进入日志。
15. 认证和授权有什么区别?
认证是证明你是谁。授权是决定你被允许做什么。它们的失败方式不同:令牌缺失或无效是 401,令牌有效但没有权限是 403。
16. 如何保护 API 免受滥用?
按密钥或按 IP 做限流、请求大小限制、输入校验、超时,以及监控异常流量。返回 429 并带上 Retry-After 头,让客户端知道何时重试。
17. HTTP 缓存对 API 是如何工作的?
响应可以携带 Cache-Control 头,说明响应可以被复用多久。ETag 标识响应的某个版本。客户端把它放在 If-None-Match 里发回,如果没有任何变化,服务器就返回 304 Not Modified,不带响应体。这能节省带宽和负载。
18. 什么是 CORS?
除非服务器允许,否则浏览器会阻止网页读取来自不同源的响应。服务器发送 Access-Control-Allow-Origin 之类的头,说明哪些源可以读取它的响应。它由浏览器强制执行,而不是服务器,所以它并不能保护 API 免受非浏览器客户端的访问。
实战
19. REST、GraphQL 还是 gRPC?
| 适合 | 代价 | |
|---|---|---|
| REST | 简单、可缓存、被广泛理解的公开 API | 对复杂界面会过度获取数据,且需要多次往返 |
| GraphQL | 需要精确挑选字段并在一次请求里组合数据的客户端 | 服务器更复杂,缓存更难 |
| gRPC | 快速、契约严格的内部服务间调用 | 对浏览器和公开使用不太友好 |
最好的回答是指出某种场景,而不是评出赢家。
20. 如何为 API 编写文档和测试?
用 OpenAPI 规范来描述它,这样可以生成文档和客户端代码。在三个层面测试:针对逻辑的单元测试、针对真实数据库的集成测试,以及用来捕捉破坏性变更的契约测试。也要试试失败场景,比如无效输入和过期令牌。
如何准备
- 要能在白板上设计一个小型 API,比如待办清单或订单系统,包括 URL、方法、状态码,以及一个错误响应。
- 把幂等性和分页烂熟于心。它们出现得最多。
- 准备一个关于你构建或使用过的 API 的故事,以及一个你下次会避免的错误。
相关练习,请参阅我们的 Spring Boot 面试问题、Node.js 面试问题、系统设计面试问题 和 计算机网络面试问题 指南。
大声练习,用自己的话讲。事后的文字记录能看出你在哪里啰嗦或跑题。在任何实时面试或评估中,都要遵守雇主关于 AI 工具的规定。
用 YesToTheOffer 练习你的回答
大声排练,获得基于你自己简历生成的答案,并在之后查看你的文字记录。30 分钟免费,无需订阅。



