目录

Api架构设计-HTTP-RESTful

Api架构设计— HTTP + RESTful

什么是RESTful

  • RESTful(Representational State Transfer)是一种基于HTTP协议设计网络应用程序接口(API)的架构风格,由Roy Fielding在2000年的博士论文中提出。其核心思想是以资源为中心,通过统一的接口对资源进行操作,实现客户端与服务器的解耦
  • 也就是RESTful是基于http定义了一组接口格式规范,用来规范所有http请求

RESTful 设计原则

核心原则

  • 资源导向(Resource-Based)
  • 所有事物抽象为资源(如用户、订单、文章),每个资源有唯一的标识符(URI,如 /users/123)。
  • 资源通过JSON与客户端交互。
  • 统一接口(Uniform Interface)
  • 定义了HTTP方法明确操作类型:

    GET:获取资源

    POST:创建资源

    PUT:更新资源(全量替换)

    PATCH:更新资源(部分修改)

    DELETE:删除资源

  • HTTP状态码标识结果

    如200 OK、404 Not Found等。

  • 无状态(Stateless)
  • 每个请求必须包含所有必要信息,服务器不保存客户端状态(如Session),提升扩展性和可靠性。
  • 可缓存(Cacheable)
  • 响应需明确是否可缓存(如通过Cache-Control头),减少重复请求
  • 客户端无需关注服务器架构细节(如负载均衡、代理层)
  • URI命名
  • 使用名词复数表示资源(如/users而非/getUser)。
  • 避免动词,用HTTP方法表达操作(如DELETE /users/123)。
  • 层级关系用/分隔(如/users/123/orders)。
  • URI中体现版本:/api/v1/users

RESTful 接口类型

GET

  • 用途:获取资源(查询数据)。

  • 特性:

    安全:不会修改服务器资源。

    幂等:多次请求结果相同。

    可缓存:响应可被浏览器或代理缓存。

  • 响应状态码:

    200 OK(成功)

    404 Not Found(资源不存在)

    304 Not Modified(缓存未更新)

GET /users/123         # 获取ID为123的用户信息
GET /users?role=admin  # 过滤角色为admin的用户

POST

  • 用途:创建新资源(或提交非幂等操作)。

  • 特性:

    非安全:会修改服务器资源。

    非幂等:多次调用可能产生不同结果(如重复提交订单)。

  • 响应状态码:

    201 Created(成功创建,响应头包含 Location: /users/456)

    400 Bad Request(请求数据不合法)

    409 Conflict(资源冲突,如重复创建)

POST /users  
Body: { "name": "Alice", "age": 30 }  # 创建新用户

PUT

  • 用途:全量更新资源(替换整个资源)。

  • 特性:

    幂等:多次调用结果一致(如重复更新同一数据,最终状态相同)。

    若资源不存在,可创建(需由服务端决定是否支持)。

  • 响应状态码:

    200 OK 或 204 No Content(更新成功)

    201 Created(资源被创建)

    404 Not Found(资源不存在且服务端不支持创建)

PUT /users/123  
Body: { "name": "Bob", "age": 25 }  # 替换用户123的所有字段

DELETE

  • 用途:删除资源。

  • 特性:

    幂等:删除后再次调用无效果。

  • 响应状态码:

    204 No Content(删除成功,无返回内容)

    404 Not Found(资源不存在)

    403 Forbidden(无权删除)

DELETE /users/123  # 删除ID为123的用户

PATCH

  • 用途:部分更新资源(仅修改指定字段)。

  • 特性:

    非幂等:连续相同请求可能导致不同结果(如递增计数器)。

    需明确传递修改的字段。

  • 响应状态码:

    200 OK 或 204 No Content

    400 Bad Request(修改格式错误)

    404 Not Found

PATCH /users/123  
Body: { "age": 26 }  # 仅更新用户123的年龄

RESTful 状态码

1xx(信息响应)

  • 100 Continue

    客户端应继续发送请求的剩余部分(用于大文件上传前的确认)。

2xx(成功)

  • 200 OK
    请求成功,

    返回响应数据(如 GET 或 PUT 请求成功)。

  • 201 Created

    资源创建成功(如 POST 请求后返回新资源的URI,响应头包含 Location: /users/123)。

  • 202 Accepted

    请求已接受但未处理完成(常用于异步任务)。

  • 204 No Content

    请求成功,但无返回内容(如 DELETE 成功或 PUT 更新后无需返回数据)。

3xx(重定向)

  • 301 Moved Permanently

    资源永久迁移到新URI(需更新书签)。

  • 302 Found

    资源临时重定向到新URI(浏览器默认行为是后续请求仍用原URI)。

  • 304 Not Modified

    资源未修改,客户端可使用缓存(配合 If-Modified-Since 头使用)。

4xx(客户端错误)

  • 400 Bad Request

    请求格式错误(如参数缺失或JSON语法错误)。

  • 401 Unauthorized

    未认证(需提供有效身份凭证,如JWT失效)。

  • 403 Forbidden

    已认证但无权限访问资源(如普通用户访问管理员接口)。

  • 404 Not Found

    资源不存在(URI无效或资源已删除)。

  • 405 Method Not Allowed

    HTTP方法不支持(如对只允许 GET 的URI发送 POST)。

  • 409 Conflict

    资源状态冲突(如重复创建同名用户)。

  • 429 Too Many Requests

    请求频率超出限制(常见于API限流)。

5xx(服务器错误)

  • 500 Internal Server Error

    服务器内部错误(通用兜底错误,需排查日志)。

  • 502 Bad Gateway

    网关或代理服务器收到无效响应(如后端服务崩溃)。

  • 503 Service Unavailable

    服务暂时不可用(如维护或过载,可配合 Retry-After 头提示重试时间)。

  • 504 Gateway Timeout

    网关或代理服务器超时(后端服务未及时响应)

RESTful Uri设计原则

对于Api的uri命名要遵守以下设计

  • 使用名词复数表示资源(如/users而非/getUser)。
  • 避免动词,用HTTP方法表达操作
  • 如DELETE /users/123,而不是DELETE /delete-users/123)。
  • 层级关系用/分隔
  • 如/users/123/orders, 而不是 /users/orders/123
  • URI中体现版本:/api/v1/users
  • 推荐使用小驼峰,比如/pet/petId
  • uri应该大小写敏感,并且推荐使用全小写
  • 以上只是建议,具体根据实际情况而定

Example:

  • 以下Api来住swagger官方例子,可以看到其实并没有严格遵守规范,比如Api里没有版本信息,命名里有动词等等

    https://i-blog.csdnimg.cn/direct/7e78be63563b4c00a0cb27fe2c0ee3ea.png

Api传参:QueryString 和 UriPath

使用 URI Path(路径参数)的场景

  • URI Path 用于标识 资源的主键 或 资源间的层级关系, 通常对应服务端的 核心数据模型。

适用场景:

  • 唯一资源标识

    通过路径参数直接定位唯一资源(如用户ID、订单ID)。

GET /users/{id}          # 获取指定ID的用户
DELETE /orders/{orderId} # 删除指定ID的订单
  • 资源层级关系

    表示资源之间的从属关系(如用户的所有订单)。

    示例:

GET /users/{userId}/orders  # 获取用户的订单列表

特点:

  • 必要性:路径参数通常是 必填 的(缺少会导致404)。
  • 语义明确:路径体现资源的唯一性和结构(如 /users/123 明确指向用户123)。
  • 缓存友好:路径参数不同的 URL 会被视为不同资源,适合缓存(如 CDN 缓存)

使用 Query String(查询参数)的场景

  • Query String 用于 过滤、排序、分页 或 附加操作, 通常是 可选 的非核心参数。

适用场景:

  • 过滤数据

    筛选符合特定条件的资源列表。

示例:
GET /users?role=admin&status=active  # 获取角色为admin且状态为活跃的用户
  • 分页与排序

    控制返回数据的范围和顺序。

示例:
GET /articles?page=2&limit=20&sort=-created_at  # 获取第二页文章,按创建时间倒序
  • 附加操作

    触发特定功能(如统计、导出格式)。

示例:
GET /reports/sales?format=csv     # 导出CSV格式的销售报表
GET /products?fields=name,price  # 仅返回名称和价格字段(字段选择)
  • 非资源标识参数

    不影响资源定位,仅修饰响应结果。

示例:
GET /search?q=restful&lang=en  # 搜索关键词"restful",语言为英文

特点:

  • 可选性: 缺少查询参数时,通常返回默认结果 (如不分页)。
  • 灵活性:参数组合自由,适合动态需求(如多种过滤条件)。
  • 幂等性:同一 Query String 的 GET 请求是幂等的(结果可缓存)

RESTful和HTTP的区别

  • RESTful并不等于HTTP,它只是基于HTTP的一些特性设定了一组设计规范
  • 类似的还有GraphQL,也是基于HTTP的特性设定了一组规范

注意事项

  • 以上只是标准的设计规范,并没有技术上的限制 ,开发者完全可以POST当PUT用,PUT当POST用,甚至POST当GET用等等,只是这样不规范,会导致程序可维护性降低
  • 现实开发中需要根据实际情况调整,最好和以前的开发风格保持一致
  • 大部分Api的设计都没有严格的遵守以上规则,比如Api的uri里没有版本信息,返回的状态码用的不准确等,使用动词等等