HTTP API 接口设计

概述

本文详细介绍了 HTTP API 的设计规范,此规范已经在本人多个线上项目中使用,前端包括 PC Web、App、小程序、H5、IoT 设备等;后端语言无特殊要求,我们常见的如 Java、Python、PHP、C# 等都可以。

HTTP 协议

1、HTTP 请求方法

在 HTTP API 设计中,要求所有请求都使用 POST 方法。

理由如下:

  • 这份接口设计不是遵循 RESTful 规范的,所以不用纠结读请求用 GET,写请求用 POST、PUT、DELETE 等
  • 使用 POST,相对于 GET 的 Query String,可以支持复杂的请求参数,即使是读请求,可以构造复杂的筛选请求结构
  • 便于对请求和响应统一做签名、加密、日志等处理

2、URL 规则

URL 设计规则如下:

  • URL 中的只能含有英文,使用英文单词或简称,不要使用汉语拼音。
  • 所有字符使用小写字母。
  • 多个单词间使用 - (hyphen,连字符)分隔,如 create-user,不要使用 createusercreateUser 或者 create_user
  • URL 的 path 部分,使用「系统/模块/操作」的格式,如 app/account/login
    • 系统,表示这个接口是给谁用的,比如 :app、web、h5、weapp 等;命名可使用简称。
    • 模块,表示系统的子模块,比如 :account(账户)、project(项目)、contract(合同)等。模块名字使用名词 全称,且使用单数形式。
    • 操作,表示这个模块的具体的接口,比如 create-user(创建用户)、list-users(用户列表)等。使用动词+名词 的形式,需要考虑单复数。对于常用的操作,可以使用习惯词语,比如 login(登录)、logout(登出)。

3、HTTP 头

关于 HTTP 头信息,将遵守以下最佳实践:

  • 将具体接口业务无关的数据放在 HTTP Headers
  • 后端系统可以在不涉及请求和响应体的情况下,处理一些公用逻辑

例如:

  • X-Access-Token:身份认证
  • X-App-Os:客户端 OS
  • X-App-Version:客户端版本
  • X-Network:客户端网络模式,Wi-Fi,蜂窝网络
  • X-Sign:请求签名

4、请求和响应体

请求和响应体的基本要求为:

  • 使用 UTF-8 编码
  • 以 JSON 作为数据交换格式
  • 如果有加密功能,可以将正常的 JSON 加密后,使用 Base64 编码

5、HTTP 状态码

HTTP 状态码的基本要求是:

  • 业务的处理结果不体现在 HTTP 状态码,由响应体的错误码字段表示
  • 只使用部分 HTTP 状态码来表示一些业务无关的响应

例如:

  • 200:业务已处理,但是业务处理成功还是失败由响应体表示
  • 400:错误的请求,多用在请求验证,客户端开发要保证向服务器提交正确格式的请求,400 错误不该在生产环 境出现
  • 401:认证失败,一般是没有 Access Token 或者已过期
  • 403:无权限,指没有权限调用这个接口,客户端应该在界面上将用户无权限的操作隐藏
  • 500:服务器发生了未处理的异常, 500 错误不该在生产环境出现

提示:欲了解更多常用的 HTTP 状态码,请参考本站提供的 HTTP 状态码参考

有关 JSON 使用的最佳实践

1、字段命名

  • 由于 JSON 来自于 JavaScript 语言,所以字段命名遵循 JavaScript 语言, 采用 lowerCamelCase (小骆驼拼写法)
  • 不要采用snake_case

2、数据类型

JSON 中常用数据类型映射:

  • bool:映射为 string,使用 Y 表示 true,N 表示 false
  • int:映射为 number
  • long:映射为 string
  • float / double / decimal:映射为 string
  • 日期  / 时间:映射为 string

特殊说明:

  • 表示 ID 概念的字段,统一使用 string
  • long 映射为 string,是因为 JavaScript 的 number 能处理的数值范围不够,会导致各种奇怪的问题

3、空值处理

在数据传输时,如果某个字段是空值,则直接省略此字段不传,以减少网络开销。

4、嵌套还是平铺?

基本原则是:嵌套优先于平铺。

比如:Project 对象有个创建者,前端要显示创建者的名字和头像,以下展示了好的设计不好的设计

不好的对象结构(使用了平铺的方式设计 JSON 字段):

{
  "id": "10",
  "name": "我的项目",
  "creatorId": "35",
  "creatorName": "张三",
  "creatorAvatar": "https://xxx.example.com/avatar.png"
}

设计良好的对象结构(使用了嵌套的方式设计):

{
  "id": "10",
  "name": "我的项目",
  "creator": {
    "id": "35",
    "name": "张三",
    "avatar": "https://xxx.example.com/avatar.png"
  }
}

5、响应体

使用 JSON 作为响应体,应包含如下必要的字段:

  • code
    HTTP 响应错误码(成功时返回 OK),任何情况下必须返回
  • message
    业务提示信息或错误信息(可选)
  • data
    业务数据,该字段是一个 Map(可选)
  • errors
    表示发生了错误。当发生 HTTP 400 错误时,存在此字段,该字段是一个 Map,Key 为发生错误的请求字段, Value 为错误描述

下面是一个响应体的示例:

{
  "code": "OK",
  "message": "新增人员成功",
  "data": {},
  "errors": {
    "title": "人员姓名不能为空",
    "age": "人员年龄必须是数字"
  }
}

6、错误码

响应体的 code 字段表示业务处理的错误码。如果业务处理成功,必须返回 OK;如果业务处理失败,则使用不同的错误码区分不同的错误

通常,错误码使用简短的能够体现错误种类的英文单词来表示,单词由大写字母组成(类似于我们定义常量时的做法),同时,使用下划线分隔单词。

为什么使用 string 而不是 int?

传统上经常使用一个数字表示错误码,但是如果错误种类比较多,维护错误码表就是一个很大的工作,因为相近的错误码数字最好连续,但是后期添加就可能导致已经定义的错误码的改动。另外,数字错误码很难一看就知道发生了什么错误;使用字符串的话,能够从文字上看出错误类型,而且错误码的添加和更新也相对独立。

总结

HTTP API 设计是一门艺术,需要在不断的设计中,不断的总结,为项目持续的良好发展保驾护航。多思考、多实践、多总结,才能设计出优良的 API 接口。希望本文对你设计 HTTP API 有所帮助。

分享