API 规范

API 规范

Filtering

如果记录数量很多,服务器不可能都将它们返回给用户。API 应该 提供参数,过滤返回结果。下面是一些常见的参数。

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数。
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
  • ?animal_type_id=1:指定筛选条件

所有 URL 参数 必须 是全小写,必须 使用下划线类型的参数形式

经常使用的、复杂的查询 应该 标签化,降低维护成本。如

1
2
3
4
GET /trades?status=closed&sort=sortby=name&order=asc

# 可为其定制快捷方式
GET /trades/recently_closed

Versioning

所有的 API 必须保持向后兼容,你 必须 在引入新版本 API 的同时确保旧版本 API 仍然可用。所以 应该 为其提供版本支持。

如在 URL 中嵌入版本编号

1
api.example.com/v1/*

API Root URL

API 的根入口点应尽可能保持足够简单,这里有两个常见的 URL 根例子:

  • api.example.com/*
  • example.com/api/*

Endpoints

端点就是指向特定资源或资源集合的 URL。在端点的设计中,你 必须 遵守下列约定:

  • URL 的命名 必须 全部小写
  • URL 中资源(resource)的命名 必须 是名词,并且 必须 是复数形式
  • 必须 优先使用 Restful 类型的 URL
  • URL 中不能出现 -必须 用下划线 _ 代替(存疑)
  • URL 必须 是易读的
  • URL 一定不可 暴露服务器架构

例如

1
2
3
4
5
https://api.example.com/zoos
https://api.example.com/animals
https://api.example.com/zoos/{zoo}/animals
https://api.example.com/animal_types
https://api.example.com/employees

HTTP 动词

对于资源的具体操作类型,由 HTTP 动词表示。常用的 HTTP 动词有下面五个(括号里是对应的 SQL 命令)。

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源。

例如

请求方法URL描述
GET/zoos列出所有的动物园 (ID 和名称,不要太详细)
POST/zoos新增一个新的动物园
GET/zoos/{zoo}获取指定动物园详情
PUT/zoos/{zoo}更新指定动物园(整个对象)
PATCH/zoos/{zoo}更新动物园(部分对象)
DELETE/zoos/{zoo}删除指定动物园
GET/zoos/{zoo}/animals检索指定动物园下的动物列表 (ID 和名称,不要太详细)
GET/animals列出所有动物 (ID 和名称)。
POST/animals新增新的动物
GET/animals/{animal}获取指定的动物详情
PUT/animals/{animal}更新指定的动物(整个对象)
PATCH/animals/{animal}更新指定的动物(部分对象)
GET/获取所有动物类型(ID和名称,不要太详细)
GET/animal_types/{type}获取指定的动物类型详情
GET/employees检索整个雇员列表
GET/employees/{employee}检索指定特定的员工
GET/zoos/{zoo}/employees检索在这个动物园工作的雇员的名单(身份证和姓名)
POST/employees新增指定新员工
POST/zoos/{zoo}/employees在特定的动物园雇佣一名员工
DELETE/zoos/{zoo}/employees/{employee}从某个动物园解雇一名员工

Response

所有的 API 响应,必须 遵守 HTTP 设计规范,必须 选择合适的 HTTP 状态码。一定不可 所有接口都返回状态码为 200HTTP 响应,如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
HTTP/1.1 200 ok
Content-Type: application/json
Server: example.com

{
    "code": 0,
    "msg": "success",
    "data": {
        "username": "username"
    }
}
复制代码

1
2
3
4
5
6
7
8
9
HTTP/1.1 200 ok
Content-Type: application/json
Server: example.com

{
    "code": -1,
    "msg": "该活动不存在",
}
复制代码

下表列举了常见的 HTTP 状态码

状态码描述
1xx代表请求已被接受,需要继续处理
2xx请求已成功,请求所希望的响应头或数据体将随此响应返回
3xx重定向
4xx客户端原因引起的错误
5xx服务端原因引起的错误
  • 200 ok
    • 在所有 成功GET 请求中,必须 返回此状态码
  • 201 Created
    • 当服务器创建数据成功时,应该 返回此状态码
  • 202 Accepted
    • 该状态码表示服务器已经接受到了来自客户端的请求,但还未开始处理。常用短信发送、邮件通知、模板消息推送等这类很耗时需要队列支持的场景中
  • 204 No Content
    • 该状态码表示响应实体不包含任何数据,其中:
      • 在使用 DELETE 方法删除资源 成功 时,必须 返回该状态码
      • 使用 PUTPATCH 方法更新数据 成功 时,也 应该 返回此状态码
  • 400 Bad Request
    • 由于明显的客户端错误(例如,请求语法格式错误、无效的请求、无效的签名等),服务器 应该 放弃该请求
    • 当服务器无法从其他 4xx 类型的状态码中找出合适的来表示错误类型时,都 必须 返回该状态码。
  • 401 Unauthorized
    • 该状态码表示当前请求需要身份认证,以下情况都 必须 返回该状态码。
      • 未认证用户访问需要认证的 API
      • access_token 无效/过期
      • 客户端在收到 401 响应后,都 应该 提示用户进行下一步的登录操作。
  • 403 Forbidden
    • 该状态码可以简单的理解为没有权限访问该请求,服务器收到请求但拒绝提供服务。
    • 如当普通用户请求操作管理员用户时,必须 返回该状态码。
  • 404 Not Found
    • 该状态码表示用户请求的资源不存在,如
      • 获取不存在的用户信息 (get /users/9999999)
      • 访问不存在的端点
    • 上述情况都 必须 返回该状态码,若该资源已永久不存在,则 应该 返回 410 响应。
  • 405 Method Not Allowd
    • 当客户端使用的 HTTP 请求方法不被服务器允许时,必须 返回该状态码。
      • 如客户端调用了 POST 方法来访问只支持 GET 方法的 API
    • 该响应 必须 返回一个 Allow 头信息用以表示出当前资源能够接受的请求方法的列表
  • 406 Not Acceptable
    • API 在不支持客户端指定的数据格式时,应该返回此状态码。如支持 JSONXML 输出的 API 被指定返回 YAML 格式的数据时
    • Http 协议一般通过请求首部的 Accept 来指定数据格式
  • 408 Request Timeout
    • 客户端请求超时时 必须 返回该状态码,需要注意的时,该状态码表示 客户端请求超时,在涉及第三方 API 调用超时时,一定不可 返回该状态码
  • 409 Gonfilct
    • 该状态码表示因为请求存在冲突无法处理。如通过手机号码提供注册功能的 API,当用户提交的手机号已存在时,必须 返回此状态码。
  • 410 Gone
    • 404 类似,该状态码也表示请求的资源不存在,只是 410 状态码进一步表示所请求的资源已不存在,并且未来也不会存在。在收到 410 状态码后,客户端 应该 停止再次请求该资源
  • 413 Request Entity Too Large
    • 该状态码表示服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。
    • 此种情况下,服务器可以关闭连接以免客户端继续发送此请求。
    • 如果这个状况是临时的,服务器 应该 返回一个 Retry-After 的响应头,以告知客户端可以在多少时间以后重新尝试。
  • 414 Request-URI Too Long
    • 该状态码表示请求的 URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。
  • 415 Unsupported Media Type
    • 通常表示服务器不支持客户端请求首部 Content-Type 指定的数据格式。如在只接受 JSON 格式的 API 中放入 XML 类型的数据并向服务器发送,都 应该 返回该状态码。
    • 该状态码也可用于如:只允许上传图片格式的文件,但是客户端提交媒体文件非法或不是图片类型
  • 429 Too Many Request
    • 该状态码表示用户请求次数超过允许范围。如 API 设定为 60次/分钟,当用户在一分钟内请求次数超过 60 次后,都 应该 返回该状态码。
  • 500 Internal Server Error
    • 该状态码 必须 在服务器出错时抛出,对于所有的 500 错误,都 应该 提供完整的错误信息支持,也方便跟踪调试。
  • 503 Service Unavailable
    • 该状态码表示服务器暂时处理不可用状态,当服务器需要维护或第三方 API 请求超时/不可达时,都 应该 返回该状态码,其中若是主动关闭 API 服务,应该在返回的响应首部加上 Retry-After 头部,表示多少秒后可以再次访问。

其他细节

请求方式说明路径请求参数 param响应参数 data
GET获取所有资源/api/todos资源对象列表
POST新增资源/api/todos资源对象
DELETE删除批量资源/api/todosid 数组对象
GET查询单个资源/api/todos/{id}资源对象
DELETE删除单个资源/api/todos/{id}
POST更新单个资源 (整个对象)/api/todos/{id}资源模型
PATCH更新单个资源 (部分属性)/api/todos/{id}待更改属性对象
GET分页查询资源/api/todos?page=1&size=20查询参数对象资源对象列表
  • 时间字段尽量字符串化
  • 关于请求
    • put 和 post 为 data
      • 请求体方式发送请求
    • get 和 delete 为 params
      • 查询参数方式发送请求
  • 访问接口传参:请求体 + 路径参数 + 查询参数
  • axios 中
    • 请求体在 param 中,作为请求体发送;
    • 路径参数在 url 中,一般从 param 里调出;
    • 查询参数在另外的形参里,一般会作为请求体发送(好像不对)
  • 只要 param 传送的是完整 json 数据,fastapi 就会判断出它是对应的 pydantic 模型,将其作为请求体,若 param 不是完整的,则会被识别为路径或查询参数(一般为查询参数,因为路径参数直接写在 url 中了,不会写在请求体中)
  • 实际上,查询参数既可以通过构建 url 发出,也可以写在请求体里发送(方法:不用封装成 json 格式,直接传参即可)。建议使用后者。因为前者不够优雅,耦合性高;而且 fastAPI 可以从请求体中将三种参数分开识别,非常方便呀
  • 新增资源时,建议在响应中返回新增资源的 json 模型,这样在前端中可以比较方便地进行页面更新操作
  • 而删除资源则不用