接口设计

予早 2024-05-30 21:27:47
Categories: Tags:

GET+POST API

基于GET和POST的接口设计

动作 前缀 备注
获取 get get{XXX}
获取 get get{XXX}List
新增 add add{XXX}
修改 update update{XXX}
保存 save save{XXX}
删除 delete delete{XXX}
上传 upload upload{XXX}
发送 send send{XXX}

公共参数

APP 端请求

参数 说明 备注
network 网络 WIFI、4G
operator 运营商 中国联通/移动
platform 平台 iOS、Android
system 系统 ios 13.3、android 9
device 设备型号 iPhone XR、小米9
udid 设备唯一标示
apiVersion API 版本号 v1.1、v1.2

WEB 端请求

参数 说明 备注
appKey 授权Key 字符串

调用方需向服务方申请 appKey(请求时使用) 和 secretKey(加密时使用)。

RESTful API

REST,即 Representational State Transfer,表现形式状态转换。REST 是一种软件架构风格,用于指导 Web 应用程序接口(Endpoint)的设计和开发。

以资源为中心的 URL 设计

基本设计原则

  1. 由HTTP方法体现动作,URL体现资源,而不是在URL中体现动作和资源

    bad:  GET /articles/get/1
    good: GET /articles/1
    
  2. 使用复数名词集合

    bad:  GET /article/1
    good: GET /articles/1
    good: GET /articles
    
  3. 嵌套体现资源关系

    good: GET /articles/1/comments/2
    

    嵌套可以很好体现资源间的关系,但应当避免超过 3 层嵌套,三层以上可能反而导致可读性降低,有过度嵌套之嫌。

基础接口设计规范

业务资源操作分类 HTTP动词 Endpoint 描述
查询 GET /resources/{recourceId} 查询单个资源(get)
查询 GET /resources?q=查询关键字&age=0,10&name=Jack&limit=10&offset=0 查询多个资源(list)
创建 POST /resources 创建单个资源(create)
替换(全部更新) PUT /resources/{recourceId} 全部更新(替换)单个资源(update)
补丁(局部更新) PATCH /resources/{resourceId} 部分更新(补丁)单个资源(update)
删除 DELETE /resources/{recourceId} 删除单个资源(delete)
业务资源操作分类 HTTP动词 Endpoint 描述
查询 GET /resources/{recourceId}/subResources/{subResourceId} 查询单个子资源(get)
查询 GET /resources/{resourceId}/subResources?q=查询关键字&age=0,10&name=Jack&limit=10&offset=0 查询多个子资源(list)
创建 POST /resources/{resourceId}/subResources 创建单个子资源(create)
替换(全部更新) PUT /resources/{recourceId}/subResources/{subResourceId} 全部更新(替换)单个子资源(update)
补丁(局部更新) PATCH /resources/{resourceId}/subResources/{subResourceId} 部分更新(补丁)单个子资源(update)
删除 DELETE /resources/{recourceId}/subResources/{subResourceId} 删除单个子资源(delete)

参数解释:

q:查询关键字

limit:此次查询多少条数据。

offset:从 0 开始的偏移量。

age=0,10:表示查询 age 为[0, 10)区间的数据,,区分起始,同样的还可应用于时间、日期等类型的数据。

age=,10;20,30;40:表示查询age[0, 10)[20,30) 以及大于40的数据,,前面表示开始值,若不提供,表示所有小于,右侧的值的值,,右侧表示结束值,若没有,则表示所有大于,左侧的值,;表示多个值的区分。

其他:

基础接口设计示例

一级资源
业务资源操作分类 HTTP动词 Endpoint 描述
查询 GET /zoos?name=gardon 获取 zoo 列表
查询 GET /zoos/{zoo_id} 根据 animal_id 获取一条zoo数据
创建 POST /zoos 创建一条 zoo 数据
替换(全部更新) PUT /zoos/{zoo_id} 根据 animal_id 更新一条 zoo 数据
补丁(局部更新) PATCH /zoos/{zoo_id} 根据 animal_id 更新一条 zoo 数据
删除 DELETE /zoos/{zoo_id} 根据 animal_id 删除一条 zoo 数据
二级资源
业务资源操作分类 HTTP动词 Endpoint 描述
查询 GET /zoos/{zoo_id}/animals 获取 zoo_id 的 animal 列表
查询 GET /zoos/{zoo_id}/animals/{animal_id} 根据 id 获取一条zoo_id的animal数据
创建 POST /zoos/{zoo_id}/animals 创建一条zoo_id的animal数据
替换(全部更新) PUT /zoos/{zoo_id}/animals/{animal_id} 根据animal_id更新一条zoo_id的animal数据
补丁(局部更新) PATCH /zoos/{zoo_id}/animals/{animal_id} 根据animal_id更新一条zoo_id的animal数据
删除 DELETE /zoos/{zoo_id}/animals/{animal_id} 根据animal_id删除一条zoo_id的animal数据

不符合基础接口设计的情况如何处理

REST 本身是一种软件架构风格,不同技术团队对 REST 的应用(或者说对 REST 的落地规范)不尽相同,但有两点是确定的,一是尽可能保证 CRUD 风格,二是保证团队内对 REST 的使用规范一致。

四类资源

整体上对 REST 的资源分为四类,前三类在基础接口设计有所体现,第四类可用于特殊场景:

  1. document:文档资源,是集合资源中的单个资源,通常对应到数据库的一行记录,资源标记 /resources/{resourceId}/subResources/{subResourceId}唯一确认一个文档资源resource
  2. collection:集合资源,是仓库资源中的一类资源,通常对应到数据库的一张表中所有数据,资源标记/resources/{resourceId}/subResources唯一确认一个集合资源sub-resources
  3. store:仓库资源,包含若干集合资源,资源标记/resources/{resourceId}/subResources中的resources即为仓库资源,只要包含集合资源即可称为仓库资源,仓库资源本身也是一类集合资源
  4. controller:控制器资源,通常表示一种行为或操作,例如发布帖子的 URL /posts/{id}/publishpublish是一种controller资源。
业务资源操作分类 HTTP动词 Endpoint 描述
行为或操作 POST /resources/{recourceId}/controller 比如通过审核、激活等对资源的操作

document、collection、store三级构成资源的层次表达,controller用于不太直观的特殊资源。

controller 资源示例
邮件重发
POST /email/1/resend
GitHub star
添加star POST https://github.com/xxx/yyy/star
取消star POST https://github.com/xxx/yyy/unstar
大型查询

B端表单复杂查询会导致GET请求URL参数拼接过长,基于临时资源的思路转换请求,创建resources的临时子资源filter然后返回结果

GET  /resources?k1=v1&k2=v2&k3=v3&k4=v4&k5=v5&k6=v6&k7=v7&k8=v8&k9=v9&k10=v10&k11=v11&k12=v12
POST /resources/filter
批量操作

batch视为controller资源

DELETE /resources/batch
整体设计示例

风格一:在基础接口设计原则基础上,批量操作使用请求体,定义 filter 应用于复杂查询场景

把基础和拓展的分开

GET /articles/{articleId}
根据articleId查询一篇文章
方法名,getArticlesOne
权限名,get:articles:one

禁止设计该接口(应用场景受限且本方案有替代)
GET /articles?name=MongoDB&star=666,
根据复杂条件查询文章列表
方法名,getArticleBatch
权限名,get:articles:batch

POST /articles
创建一篇或多篇文章
方法名,postArticlesOneOrBatch
权限名,post:articles:one_or_batch

PUT /articles/{articleId}
根据articleId全部更新一篇文章
方法名,putArticlesOne
权限名,put:articles:one

PUT /articles
全部更新多篇文章
方法名,putArticlesBatch
权限名,put:articles:batch

PATCH /articles/{articleId}
根据articleId局部更新一篇文章
方法名,patchArticlesOne
权限名,patch:articles:one

PATCH /articles
局部更新多篇文章
方法名,patchArticlesBatch
权限名,patch:articles:batch

DELETE /articles/{articleId}
根据articleId删除一篇文章
方法名,deleteArticlesOne
权限名,delete:articles:one

DELETE /articles
根据articleId删除多篇文章
方法名,deleteArticlesBatch
权限名,delete:articles:batch

POST /articles/filter
创建filter临时资源,返回过滤结果,针对复杂条件查询场景
方法名,postArticlesFilter
权限名,post:articles:filter

风格二:在基础接口设计原则基础上,定义 batch 资源用于批量操作场景,定义 filter 资源用于复杂条件过滤场景

GET /articles/{articleId}
根据articleId查询一篇文章
方法名,getArticlesOne
权限名,get:articles:one

禁止设计该接口(应用场景受限且本方案有替代)
GET /articles?name=MongoDB&star=666,
根据复杂条件查询文章列表
方法名,getArticlesBatch
权限名,get:articles:batch

POST /articles
创建一篇文章
方法名,postArticlesOne
权限名,post:articles:one

POST /articles/batch
创建多篇文章
方法名,postArticlesBatch
权限名,post:articles:batch

PUT /articles/{articleId}
根据articleId全部更新一篇文章
方法名,putArticlesOne
权限名,put:articles:one

POST /articles/batch
全部更新多篇文章
方法名,postArticlesBatch
权限名,post:articles:batch

PATCH /articles/{articleId}
根据articleId局部更新一篇文章
方法名,patchArticlesOne
权限名,patch:articles:one

POST /articles/batch
局部更新多篇文章
方法名,postArticlesBatch
权限名,post:articles:batch

DELETE /articles/{articleId}
根据articleId删除一篇文章
方法名,deleteArticlesOne
权限名,delete:articles:one

POST /articles/batch
根据articleId删除多篇文章
方法名,postArticlesBatch
权限名,post:articles:batch

POST /articles/filter
创建filter临时资源,返回过滤结果,针对复杂条件查询场景
方法名,postArticlesFilter
权限名,post:articles:filter

使用 HTTP 状态码表示操作结果

常见 HTTP 状态码

1xx,信息状态码

表示服务器已接收请求并且客户端应继续请求。

Status Code Reason Phrase 解释 场景
100 Continue 表示客户端可以继续其请求
101 Switching Protocols 服务器已理解客户端的请求,并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求 用户打开聊天应用,应用通过HTTP协议加载初始页面。用户点击连接按钮,前端JavaScript代码创建WebSocket连接。在这个过程中,浏览器首先发出HTTP请求来切换协议,服务器返回101状态码表示切换成功,然后开始使用WebSocket协议进行双向通信。这种协议切换对于需要低延迟、实时双向通信的应用场景非常有用,比如聊天室、实时游戏、股票行情推送等。
2xx,成功状态码

表示请求已成功被服务器接收、理解并处理。

Status Code Reason Phrase 解释 场景
200 OK 请求成功,并返回所请求的资源 通用成功状态码。
201 Created 请求成功并在服务器上创建了新的资源 POST 请求在服务器写入了一条数据
202 Accepted 请求已接受,但尚未处理完毕 客户端请求启动一个异步大文件处理任务,服务器返回任务 taskId、taskStatus 和 taskUrl。
204 No Content 请求成功,但没有内容返回
3xx,重定向状态码

表示请求需要进一步操作才能完成。

Status Code Reason Phrase 解释 场景
301 Moved Permanently 请求的资源已被永久移动到新位置
302 Found 请求的资源临时从不同的URI响应请求
304 Not Modified 资源未修改,自上次请求后未更改,因此可以使用缓存的版本
4xx,客户端错误状态码

表示客户端可能发生了错误,阻碍了服务器的处理。

Status Code Reason Phrase 解释 场景
400 Bad Request 服务器无法理解请求的格式
401 Unauthorized 请求需要用户认证
403 Forbidden 服务器理解请求但拒绝执行
404 Not Found 请求的资源未找到
405 Method Not Allowed 请求的方法被禁用
409 Conflict 请求与服务器的当前状态冲突
5xx,服务器错误状态码

表示服务器在处理请求时发生了错误。

Status Code Reason Phrase 解释 场景
500 Internal Server Error 服务器遇到未知错误
501 Not Implemented 服务器不支持请求的功能
502 Bad Gateway 服务器作为网关或代理时,从上游服务器接收到无效响应
503 Service Unavailable 服务器当前无法处理请求,通常是由于过载或维护
504 Gateway Timeout 服务器作为网关或代理时,未及时从上游服务器收到响应

REST 对 HTTP 状态码的使用

  1. GET - 用于获取资源。

    • 200 OK: 请求成功,资源被返回。
    • 204 No Content: 请求成功,但没有内容返回(比如查询没有结果)。
    • 301 Moved Permanently: 资源已永久移动到新位置。
    • 302 Found: 临时重定向。
    • 304 Not Modified: 资源未修改,可以使用缓存的版本。
    • 404 Not Found: 请求的资源不存在。
    • 406 Not Acceptable: 无法提供客户端接受的响应格式。
  2. POST - 用于创建新的资源。

    • 201 Created: 新资源成功创建,通常与Location头部一起返回新资源的URI。
    • 202 Accepted: 请求已被接受,但尚未完成。
    • 400 Bad Request: 请求无效或格式错误。
    • 401 Unauthorized: 请求未经授权。
    • 403 Forbidden: 服务器理解请求但拒绝执行。
    • 409 Conflict: 请求与现有资源冲突。
    • 415 Unsupported Media Type: 请求的媒体类型不被服务器支持。
  3. PUT - 用于更新现有资源或创建新资源(如果资源不存在)。

    • 200 OK: 资源更新成功。
    • 201 Created: 新资源创建成功。
    • 204 No Content: 资源更新成功,但没有内容返回。
    • 400 Bad Request: 请求无效或格式错误。
    • 401 Unauthorized: 请求未经授权。
    • 403 Forbidden: 服务器理解请求但拒绝执行。
    • 404 Not Found: 请求的资源不存在。
    • 409 Conflict: 请求与现有资源冲突。
  4. DELETE - 用于删除资源。

    • 200 OK: 资源删除成功。
    • 202 Accepted: 请求已被接受,但尚未完成。
    • 204 No Content: 资源删除成功,没有内容返回。
    • 400 Bad Request: 请求无效或格式错误。
    • 401 Unauthorized: 请求未经授权。
    • 403 Forbidden: 服务器理解请求但拒绝执行。
    • 404 Not Found: 请求的资源不存在。
  5. PATCH - 用于部分更新资源。

    • 200 OK: 资源部分更新成功。
    • 204 No Content: 资源部分更新成功,没有内容返回。
    • 400 Bad Request: 请求无效或格式错误。
    • 401 Unauthorized: 请求未经授权。
    • 403 Forbidden: 服务器理解请求但拒绝执行。
    • 404 Not Found: 请求的资源不存在。
    • 409 Conflict: 请求与现有资源冲突。
  6. HEAD - 与GET类似,但只返回头部信息,不返回响应体。

    • 200 OK: 请求成功,头部信息返回。
    • 204 No Content: 请求成功,但没有内容返回。
    • 404 Not Found: 请求的资源不存在。
  7. OPTIONS - 用于获取服务器支持的HTTP方法。

    • 200 OK: 请求成功,返回允许的方法列表。
    • 204 No Content: 请求成功,但没有内容返回。

通用过滤条件

排序

先按照 starNum 升序排序,再按照 createdTime 降序排序。

风格一:

POST /articles/filter
{
    "orderBy": ["+starNum", "-createdTime"]
}

分页

偏移分页

风格一:

POST /articles/filter
{
    "page": 2,
    "num": 10
}

风格二:

POST /articles/filter
{
    "offset": 10,
    "limit": 10
}

游标分页

POST /articles/filter
{
    "scroll_id": 10,
    "limit": 10
}

接口版本划分

Ref

  1. https://docs.github.com/zh/rest
  2. https://www.ruanyifeng.com/blog/2014/05/restful_api.html
  3. https://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html
  4. https://ics.uci.edu/~fielding/pubs/dissertation/top.htm
  5. OpenAPI,https://openapi.apifox.cn/
  6. RESTful API,https://restful.p2hp.com/
  7. https://github.com/bolasblack/http-api-guide

其他特殊情况,页面资源

  1. H5 页面中有私募频道页用于综合展示私募产品相关的信息
  2. 网站首页会展示各种产品、公司、经理等的综合信息

类似这种聚合页面(并不侧重某一大类数据资源的页面),采用如下设计方式:

  1. 首先确认该页面中的所有数据是否可以拆分为多个接口,例如PC首页大体上有产品信息和资讯信息,其他都是静态数据或其他可拆的小接口,整体上是可拆的
  2. 其次确认是否要有一个页面主接口,若一些页面有一些跟页面强相关的数据,可能需要专门为该页面开一个接口,例如 POST /ds/v1/homepage,若不需要,则全部拆分,优先采用前端服务端渲染而非后端手动聚合(下游服务调用上游服务,聚合优先放在下游)
  3. 最后确认是否可以复用原有接口,首页需要资讯数据,若可以复用 POST /ds/v1/news/filter 返回数据则复用,若不可复用,则优先使用 POST /ds/v1/pc/homepage/news/filter 形式

举例:

PC 端网站首页

  1. 可以拆分为 获取产品数据的接口 和 获取资讯数据的接口,整体可拆
  2. 无需主接口,使用服务端渲染方式聚合数据
  3. 不复用原有接口
HTTP动词 Endpoint 描述 备注
POST /ds/v1/homepage/pc/products/filter 查询多个资源 查询产品数据(PC主页专用)
POST /ds/v1/homepage/pc/news/filter 查询多个资源 查询资讯数据(PC主页专用)