教程
⚙️

后端开发

Node.js、Python、Go 等服务端开发与 API 设计。

API 设计基础:搞懂 REST、HTTP 方法与状态码

从"API 到底是什么"讲起,理解 REST 风格、HTTP 方法(GET/POST/PUT/DELETE)的语义,以及常见状态码的含义,建立设计接口的第一性原理。

· 更新于 2026-07-20 阅读量 --

你写的后端代码,最终是要”被别人调用”的——可能是前端页面、可能是另一个服务、可能是手机 App。这个”调用方和被调用方之间的约定”,就是 API(Application Programming Interface,应用程序编程接口)。而今天最主流的 API 风格,叫 REST,它建立在 HTTP 协议之上。

很多新手写接口时很随意:所有操作都用 POST、路径乱起名、返回码永远 200。结果前端同学拿到接口一脸懵,联调天天吵架。这一篇我们建立 API 设计的”第一性原理”:什么是 REST、HTTP 方法怎么用才对、状态码到底代表什么。

API 到底是什么

打个比方:餐厅里你(顾客)看不到后厨怎么炒菜,但你能通过”菜单 + 服务员”点到菜。API 就是那个”菜单”——它告诉你”我能提供哪些能力、你要传什么参数、我会返回什么”。你不需要知道后端数据库怎么存、逻辑怎么算,只要按约定发请求,就能拿到结果。

一个典型的 REST API 请求长这样:

GET /api/users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer xxxx

它表达的是:“请给我 id 为 123 的用户信息”。后端处理后返回 JSON 数据。这就是 API 的日常形态。

什么是 REST

REST(Representational State Transfer,表现层状态转移)是一套设计风格(不是标准、不是协议)。它有几个核心约束,记住这几点就够入门:

  • 资源由 URL 唯一标识:每个”东西”(用户、订单、文章)都是一个资源,用路径表示,比如 /users/123
  • 用 HTTP 方法表达”动作”:对同一个资源,GET 是查、POST 是增、PUT 是改、DELETE 是删。
  • 无状态:每次请求都自带全部信息(比如身份令牌),服务器不”记着”上一次你是谁。这样服务才能轻松横向扩展。
  • 返回统一的数据格式:通常是 JSON,前后端都好解析。

符合这些约束的 API,就叫”RESTful API”。它最大的好处是直观——看 URL 和方法,就知道在干什么。

HTTP 方法:别再全用 POST 了

这是新手最爱踩的坑。HTTP 早就定义好了一套”语义动词”,REST 把它们映射到”增删改查”:

方法语义典型场景是否幂等
GET查询,不修改数据获取用户列表、详情
POST新建资源注册用户、提交订单
PUT整体替换资源更新用户全部信息
PATCH部分更新资源只改用户昵称
DELETE删除资源注销账号

几个容易混的点:

  • 幂等的意思是”多次调用效果一样”。GET 查一百次还是那个数据,所以幂等;POST 提交一百次可能建一百个订单,所以不幂等。理解幂等对”重试安全”很重要——网络抖动时,幂等接口可以放心重试。
  • PUT vs PATCH:PUT 是”把整个资源换成新的”(没传的字段会被清空),PATCH 是”只改你传的字段”。前端部分更新用 PATCH 更友好。
  • GET 不能有请求体:查询参数都放 URL(?id=1)或路径里,别把复杂查询塞进 GET 的 body(很多网关、缓存不认)。

正确示例:

GET    /users          # 查列表
GET    /users/123      # 查详情
POST   /users          # 新建用户
PUT    /users/123      # 整体更新 123
PATCH  /users/123      # 部分更新 123
DELETE /users/123      # 删除 123

状态码:让”结果”自己说话

HTTP 状态码是服务器告诉客户端”这次请求怎么样了”的标准化数字。别总返回 200 然后在 body 里写 {"code":500,"msg":"失败"}——那是把 HTTP 协议的能力浪费了。常用状态码分五类:

  • 2xx 成功200 OK(通用成功)、201 Created(创建成功,常配合 POST)、204 No Content(成功但无返回体,如删除)。
  • 3xx 重定向301/302 跳转,API 里较少用。
  • 4xx 客户端错误400 Bad Request(参数错)、401 Unauthorized(未登录/无身份)、403 Forbidden(已登录但没权限)、404 Not Found(资源不存在)、409 Conflict(冲突,如重复创建)、422 Unprocessable Entity(参数格式对但语义错)。
  • 5xx 服务端错误500 Internal Server Error(代码崩了)、502 Bad Gateway(上游挂了)、503 Service Unavailable(过载/维护)。

关键认知:4xx 是客户端的锅(参数错、没登录),5xx 是服务端的锅(代码 bug、依赖挂了)。这个区分让前端和运维一眼就能甩锅定位问题。

一个设计良好的接口长什么样

综合上面三点,一个”查用户”的接口应该是:

请求:GET /api/users/123
响应:200 OK
{
  "id": 123,
  "name": "小明",
  "age": 18
}

而”创建用户失败因为没填名字”应该是:

请求:POST /api/users  (body 缺少 name)
响应:400 Bad Request
{
  "error": "name 不能为空"
}

注意:状态码是 400(客户端参数错),不是 200 包个错误码。这样任何 HTTP 客户端、监控、网关都能直接基于状态码做判断。

常见新手坑

  • 所有接口都用 POST:丢失了 HTTP 方法的语义,缓存、幂等、网关规则全失效。能用 GET 查的就用 GET。
  • 永远返回 200:把错误塞进 body,导致监控、重试逻辑无法基于状态码工作,联调时极难排查。
  • 把动词当资源/getUser/deleteUser 这种路径是”RPC 风格”,不是 REST。应改成 /users/{id} 配 GET/DELETE。
  • 混淆 401 和 403:401 是”你是谁?没凭证”;403 是”我知道你是谁,但你没权限”。语义不同,前端提示也不同。
  • GET 请求带敏感 body:查询参数在 URL 里,会被日志、浏览器历史记下来,密码、token 绝不能放 GET。

实战:为一个”待办事项”设计 REST 接口

假设要做任务管理,资源是 todos,合理的接口集应该是:

GET    /todos           # 列表(支持 ?status=done&page=1)
GET    /todos/1         # 详情
POST   /todos           # 新建(body: {title, content})
PUT    /todos/1         # 整体改
PATCH  /todos/1         # 改状态(body: {status:"done"})
DELETE /todos/1         # 删除

这套设计的好处:前端同学看一眼就知道每个接口干嘛、用什么方法、传什么;后端也容易按资源拆分模块。这就是 REST 带来的”约定优于配置”。

新手怎么把 API 基础打牢

API 设计是后端工程师的”门面”,设计烂了前端天天来找你。建议每天看一个公开 API(比如 GitHub API、天气预报 API),对着它的 URL 和方法,思考”它为什么这么设计”。重点是强迫自己遵守语义:查就用 GET、建就用 POST、改就用 PUT/PATCH、删就用 DELETE,别偷懒全 POST。

另一个心法:状态码是你的免费信号系统。它不占你一行业务代码,却能让网关、监控、前端、运维都受益。从今天起,错误就返回对应的 4xx/5xx,成功就返回对应的 2xx,别再 200 包一切。

还有,理解”无状态”对后端扩展的意义。如果你的服务”记着”每个用户的上一次请求状态(比如存在服务器内存里),那这个服务就不能随便加机器——因为用户下次可能落到另一台机器上,状态就丢了。REST 要求每次请求自带凭证,正是为了让你能水平扩展。

小测验:看看你掌握了没

  • 问题一:POST 和 PUT 在”幂等”上有什么区别?答案:POST 不幂等(多次可能建多个资源),PUT 幂等(多次整体替换结果一样)。
  • 问题二:401 和 403 分别是什么意思?答案:401 是未认证(没身份),403 是已认证但无权限。
  • 问题三:为什么查询接口不该用 POST?答案:GET 可被缓存、幂等、参数在 URL;POST 查数据会失去这些特性,也不符合 REST 语义。

这一篇你该记住的

  • API 是”调用方与被调用方的约定”;REST 是基于 HTTP 的设计风格。
  • REST 核心:资源用 URL 标识、用 HTTP 方法表动作、无状态、返回 JSON。
  • 方法语义:GET 查、POST 建、PUT 整体改、PATCH 部分改、DELETE 删;注意幂等性。
  • 状态码是免费信号:2xx 成功、4xx 客户端错、5xx 服务端错,别总返回 200。
  • 设计良好 = “看 URL + 方法就知道在干嘛”,约定优于配置。

下一篇我们讲 URL 与资源设计:怎么给资源起名、怎么设计嵌套、怎么处理过滤排序分页,把”能跑”提升到”好看又好用”。