← 返回 FDE 培养总览 FDE 培养 · 知识点深化 · RESTful API 设计
知识点深化 · API 设计

RESTful API 设计:资源命名、状态码、版本化、认证与 OpenAPI 规范

前端和后端怎么约定?一个好 API 应该"看 URL 就知道操作什么,看状态码就知道结果"。这一页不讲大道理,直接给你一套能照着写的规范:URL 怎么命名、GET/POST/PUT/DELETE 怎么用、状态码什么时候返回、怎么版本化、怎么鉴权,并用 OpenAPI(Swagger) 把接口文档自动生成出来。

① 小白第一课怎么学(4 步走,约 80 分钟)

先抓住"资源"这个核心词,REST 就是围绕资源做操作。

1建立资源思维(15 分钟)
读②③:URL 表示"名词资源",HTTP 方法表示"动作"。
2记状态码表(20 分钟)
读④:2xx/4xx/5xx 各代表什么,常用的那几个。
3设计一个资源 CRUD(30 分钟)
跟着⑤把"订单"的增删改查接口设计出来。
4排错+刷题(15 分钟)
读⑥命名/状态码坑,做⑦⑩。
本课小目标学完你要能:① 用名词设计 URL;② 正确选用 HTTP 方法和状态码;③ 设计 API 版本化方案;④ 用 OpenAPI 描述一个接口。

② 一图看懂:RESTful 资源模型

RESTful API URL=资源(名词) /orders /users HTTP方法=动作 GET/POST/PUT/DELETE 状态码=结果 2xx成功 4xx客户端错 认证+版本化 Bearer Token /v1/ OpenAPI 文档 Swagger 自动生成 易错:URL用动词/状态码乱用 /getOrder 这种
读法:REST = URL 表示哪个资源(名词复数)+ HTTP 方法表示干什么 + 状态码表示结果。不要在 URL 里写动词。

③ 本质直觉:把网络当成"对资源的增删改查"

想象你在操作一个数据库,但通过网络。系统里有一堆"资源":用户、订单、文章。REST 就是约定一套统一的姿势去操作它们。

URL 是名词,不是动词:你要操作"订单"这个资源,URL 就叫 /orders。是查、是增、是删,靠 HTTP 方法区分,而不是写成 /getOrder、/createOrder。

用复数名词:/orders 是订单集合,/orders/123 是 123 号订单。嵌套表示从属:/users/1/orders 是用户 1 的订单。

方法对应动作:GET 查、POST 增、PUT/PATCH 改、DELETE 删。同样一个 /orders/123,用不同方法就是不同操作。这套约定的好处是:前端看到 DELETE /orders/123 立刻懂"删 123 号订单",不用翻文档。

/orders (资源名词) GET 查列表 POST 新建 PUT 更新 DELETE 删 同一个 URL,方法不同=动作不同 不要写 /getOrders /addOrder
为什么用复数名词因为 URL 指向的是"资源集合"这个概念。/user 和 /users 规范上用后者;单数 /orders/123 里的 123 才是单个资源。保持一致,团队就不用每次纠结。

④ 完整体系:命名、方法、状态码、版本化、OpenAPI

HTTP 方法语义

方法语义示例幂等
GET查询资源GET /orders?status=paid是
POST新建资源POST /orders否
PUT整体替换PUT /orders/123是
PATCH局部更新PATCH /orders/123 {status}否
DELETE删除DELETE /orders/123是

必记状态码

状态码含义何时返回
200 OK成功查询/更新成功
201 Created已创建POST 新建成功,返回 Location
204 No Content成功无返回体DELETE 成功
400 Bad Request参数错请求体格式/字段不合法
401 Unauthorized未认证没带 token 或 token 失效
403 Forbidden无权限已登录但不能操作此资源
404 Not Found资源不存在查/删不存在的 id
409 Conflict冲突唯一约束重复(如用户名已存在)
422 Unprocessable语义错格式对但业务不通过
500 Internal Error服务器错后端崩溃

URL 命名规范

做法推荐不推荐
名词复数/orders/getOrders
小写连字符/order-items/OrderItems
嵌套/users/1/orders深层无限嵌套(≤2 层)
过滤/分页?page=2&size=20塞进路径

版本化与认证

版本化:破坏性变更时用 /v1/orders、/v2/orders,老客户端继续用 v1。

认证:用 Bearer Token,放在请求头 Authorization: Bearer <token>。不要把 token 放 URL(会进日志)。

OpenAPI 片段(Swagger)

openapi: 3.0.0
paths:
  /orders:
    get:
      summary: 查询订单列表
      parameters:
        - {name: status, in: query, schema: {type: string}}
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema: {type: array, items: {$ref: '#/components/schemas/Order'}}

FastAPI/Express 配 swagger 后,访问 /docs 自动出可交互文档。

⑤ 用法场景与典型例题

例1(设计 CRUD)为"订单"资源设计一套增删改查接口
URL 用名词,方法用动作。
① 查询列表:GET /orders?page=1。
② 查询单个:GET /orders/123。
③ 新建:POST /orders(返回 201)。
④ 全量更新:PUT /orders/123;局部更新:PATCH /orders/123。
⑤ 删除:DELETE /orders/123(返回 204)。
答案:围绕 /orders 和 /orders/{id} 五个方法,不用写动词 URL。
例2(状态码)前端提交了一个不存在的订单 id,后端应返回?
资源不存在。
① 该订单在数据库里没有。
② 应返回 404 Not Found,body 带错误说明。
③ 不要返回 200 空数组(那是"列表查无",不是"单资源不存在"),也不要 500。
答案:GET /orders/999 不存在 → 404。
例3(认证)用户没登录就访问 /orders,返回什么?已登录但不是自己的订单呢?
区分"没认证"和"没权限"。
① 没带 token / token 失效 → 401 Unauthorized(你是谁都不知道)。
② 带了有效 token,但这个订单属于别人 → 403 Forbidden(知道你是谁,但不让你动)。
答案:401=没登录;403=登录了但没权限。两者别混。
错误返回体统一格式建议所有错误返回 {"error": {"code": "NOT_FOUND", "message": "订单不存在"}},前端好统一处理。

⑥ 高频错误诊断(4 条)

错误 1:URL 里写动词常见 /getUser?id=1、/createOrder。REST 里动作该由 HTTP 方法表达,URL 只放名词。正确是 GET /users/1、POST /orders。
错误 2:状态码乱用,全返回 200失败也返回 200 + body 里写 success:false,让前端没法靠状态码判断。该 400/404/500 就老实返回对应码。
错误 3:把 token 放 URL query/orders?token=xxx 会被浏览器历史、Nginx 日志记录,泄露。放 Authorization 头。
错误 4:破坏性变更不做版本直接改 v1 接口的字段,老客户端全崩。破坏性变更新开 /v2/,v1 保留并标注废弃。

⑦ 考点真题演练(4 题)

考点分布

考法出题形式应对
命名挑出不规范 URL名词复数,无动词
方法操作选方法GET查 POST增 PUT改 DELETE删
状态码场景选码401/403/404 分清
认证token 放哪Authorization 头

真题基础1. 下列哪个 URL 符合 RESTful 规范?

真题中档2. 删除一个订单资源,应使用哪个方法?

真题中档3. 已登录用户试图访问别人的订单,应返回?

真题拔高4. POST 创建订单成功,最恰当的状态码是?

⑧ 必背命令/知识点卡

URL:名词复数 /orders,不写动词 小写连字符
方法:GET查 POST增 PUT改 PATCH局部 DELETE删 动作在方法里
成功:200 查改 / 201 新建 / 204 删除 别全用200
客户端错:400 参数 / 401 未登录 / 403 无权限 / 404 不存在 分清401和403
服务端错:500 内部错 别把业务错当500
认证:Authorization: Bearer <token> 不放URL
版本:/v1/ /v2/,破坏性变更才开新版 向后兼容

⑨ 应用输出:设计一套"文章"API 并出文档

场景:博客系统,需要文章的增删改查,且要给前端看文档
① 定资源:文章资源 = /articles。
② 列接口:GET /articles(分页+搜索)、GET /articles/{id}、POST /articles、PUT /articles/{id}、DELETE /articles/{id}。
③ 定状态码:POST 成功 201;删成功 204;文章不存在 404;未登录 401;非作者改文章 403。
④ 鉴权:除 GET 列表/详情外,写操作都要 Bearer Token,后端校验是否作者本人。
⑤ 写 OpenAPI:用 FastAPI 装饰器自动生成,访问 /docs 出 Swagger 交互页,前端可直接试调。
⑥ 版本:当前 /v1/articles;以后大改再开 /v2/。
口述设计思路"把文章当资源,URL 用名词复数,方法定动作,状态码如实返回结果,写操作加 token 鉴权,最后用 OpenAPI 自动出文档。"

⑩ 分层练习 15 题(基础 5 + 中档 5 + 拔高 5)

▍基础 5 题

基础1RESTful 的 URL 应该用名词还是动词?
名词(资源),动作由 HTTP 方法表达。
基础2查询资源用哪个方法?
GET。
基础3201 状态码表示什么?
资源创建成功,通常是 POST 后返回。
基础4401 和 403 的区别?
401=未认证(没登录);403=已认证但无权限。
基础5token 应该放在哪里?
请求头 Authorization: Bearer xxx,不放 URL。

▍中档 5 题

中档6PATCH 和 PUT 的区别?
PUT 整体替换资源;PATCH 只更新部分字段。
中档7删除成功返回什么状态码?
204 No Content(无返回体)。
中档8分页参数放哪?
query string,如 /orders?page=2&size=20。
中档9客户端传的 JSON 缺必填字段,返回?
400 Bad Request,说明哪个字段错。
中档10为什么破坏性变更要加 /v2/?
保护老客户端不崩;v1 继续可用,新客户端用 v2。

▍拔高 5 题

拔高11PUT /users/1 重复发两次结果一样吗?这叫什么?
一样,叫幂等。PUT/DELETE/GET 都应幂等;POST 不是。
拔高12用户名已被注册,注册接口返回什么?
409 Conflict(唯一约束冲突),body 说明冲突字段。
拔高13OpenAPI 的价值是什么?
机器可读的接口描述,可自动生成文档、SDK、Mock,前后端契约清晰。
拔高14为什么不建议在 URL 里传动作如 /search?
搜索不是资源,但实在需要可接受;更 REST 的做法是 GET /resources?q=kw。保持资源导向。
拔高15后端内部错误 vs 业务规则不满足,状态码怎么分?
业务不满足(如余额不足)用 4xx(422/400)+ 业务码;真正代码崩溃/依赖挂了才用 500。

⑪ 记忆口诀 + 7 天复习计划

三句口诀 ① URL 是名词复数,动作交给 HTTP 方法。
② 成功 200/201/204,客户端错 400/401/403/404。
③ token 放头不放 URL,破坏性变更开 v2。
天任务自检
第 1 天读②③,画一遍资源模型能分清名词和动词
第 2 天背状态码卡 + 做基础 1-5基础全对
第 3 天设计文章 CRUD 五个接口方法状态码对
第 4 天做中档 6-10,区分 401/403/404不混
第 5 天做拔高 11-15 + 真题 4 题会写 OpenAPI
第 6-7 天口述一套 API 设计规范,默写状态码表不看资料全默对

← 返回 FDE 培养总览