一、协作流程规范
在团队协作中,每个人都会提交git commit message,但是由于每个人的开发风格和书写习惯的不同,导致git提交五花八门,不利于维护和阅读。一般来说,大厂都一套自己的代码提交规范的,尤其是在开源项目中,代码提交规范都是一致的。
1、需求分析。确保大家对需求有一致的认知
2、设计接口文档。前端需要确认是否符合要求
3、并行开发。前端需要根据接口文档进行Mock, 模拟对接后端接口;联调之前,要求后端做好接口测试
4、真实环境联调。前端将接口请求代理到后端服务,进行真实环境联调。
二、接口规范
2.1 接口风格:
RESTful —— 推荐
JSONRPC
2.1.1 RESTful
标准格式
http(s)://server.com/app-name/{version}/{domain}/{rest-convention}
用法
GET
GET /api/teams (对应团队列表)
GET /api/teams/123 (对应 ID 为 123 的团队)
GET /api/teams/123/members (对应 ID 为 123 的团队下的成员列表)
GET /api/teams/123/members/456 (对应 ID 为 123 的团队下 ID 为 456 的成员)
POST
用于创建资源,或者特殊资源提交(如文件上传/下载)
POST /api/teams/123/members/456 (新增ID 为 123 的团队下 ID 为 456 的成员信息)
body参数{name:'xxx'}
POST /api/teams/123/members/456 (下载ID 为 123 的团队下 ID 为 456 的成员信息)
POST /api/teams/123/members/456 (上传ID 为 123 的团队下 ID 为 456 的成员信息)
body参数{file:formData}
UPDATE(PUT和PATCH)
PUT 用于更新资源的全部信息,在请求的 body 中需要传入修改后的全部资源主体
PATCH 用于局部更新,在 body 中只需要传入需要改动的资源字段。
POST /api/teams (创建团队)
POST /api/teams/123/members (创建团队ID 为 123 的成员)
PUT /api/teams/123/members/456 (更新ID 为 123 的团队下 ID 为 456 的成员全部信息)
PATCH /api/teams/123/members/456 (更新ID 为 123 的团队下 ID 为 456 的成员部分信息)
DELETE
// 单个删除
DELETE /api/users/123
// 批量删除
DELETE /api/users
body参数{ids:[]}
HEAD
获取一个资源的元数据,如数据的哈希值或最后的更新时间。
OPTIONS
获取客户端能对资源做什么操作的信息
过滤
?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置。
?page=2&size=100:指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
?keyname=1:指定筛选条件复制代码
其他规范:
规则1:URI结尾不应包含(/)
规则2:正斜杠分隔符(/)必须用来指示层级关系
规则3:应使用连字符(-)来提高URI的可读性
规则4:不得在URI中使用下划线(_)
规则5:URI路径中全都使用小写字母
2.2 注意点:
明确数据类型。例如数字应为Int或Float类型,而非String类型
明确空值的意义。比如在做更新操作时,空值是表示重置,还是忽略更新
明确默认值。对象类型的返回空对象{}, 数组类型的返回空数组[],字符串类型的返回空字符串"",Number和Boolean类型的返回null
对于大数字(如Java的long 类型,整数类型大于16位浮点数类型大于18位),返回给前端时需要设置为字符串类型, 防止js发生溢出
关于日期时间格式
对于需要前端再次处理的日期值, 可以使用时间戳
对于纯展示用的日期值, 推荐返回格式化文本, 例如: 2017年1月1日或2017-01-01 20:00:00
对于日期时间需要排序时,返回时间戳或者格式化的包含毫秒数的文本
建议同时返回时间戳的原始值(或 ISO 标准格式)和用于统一显示的格式化文本,例如: {"createTime": 1543195480357, "createTimeText": "2018年11月26日"}
关于分页
分页计数,从1开始
避免滚动加载可能出现的重复数据,采用 lastId 分页方式
图片URL
图片的 URL 建议返回完整的 URL,协议为HTTP时可省略协议
文件上传/下载
文件上传限制默认最大为10M
文件上传类型默认支持:
文档类:doc、docx、xls、xlsx、ppt、pptx、pdf、txt
图片类:jpg、jpeg、png、gif
其他:zip、rar
多文件上传不支持IE9及以下版本浏览器
图片上传服务器前需先在前端压缩,默认控制在400万以下像素或2560*1440及以下分辨率
响应避免冗余的嵌套
接口版本化,保持向下兼容;接口不兼容时需升级版本
建议使用Swagger等工具,避免人工维护可能导致的代码和文档不同步
鉴权通过header实现
同时给出 ID 字段和用于显示字段时,前端提交只提交ID字段
2.3 接口文档规范
后端通过接口文档向前端暴露接口相关的信息。通常需要包含这些信息:
版本号
文档描述
服务的入口,例如协议、域名、基本路径
测试服务器,可选
简单使用示例
安全和认证
具体接口定义
方法名称或者URI
方法描述
请求参数及其描述,必须说明类型(数据类型、是否可选等)
响应参数及其描述, 必须说明类型(数据类型、是否可选等)
可能的异常情况、错误代码、以及描述
请求示例,可选
2.3.1 Header
Content-Type
application/json 默认
application/x-www-form-urlencoded 表单提交/APP请求
Authorization
Basic XXXXXXXX
Bearer XXXXXXXX
Cookie
openid = hash(appid+uid)
Expires 过期时间,默认为0
Referer 之前页面URL,跳转第三方地址需要此参数
lang 多语言
zh_cn
zh_hk
en_us
2.3.2 请求参数
4种类型:
1、cookie: 一般用于OAuth认证
2、Request Header: 一般用于OAuth认证
3、请求body数据
4、地址栏参数: 详见【2.1.1过滤】
2.3.3 响应参数
response Demo
-
表示不必须
{status: 200, // 详见【status】
data: {
code: 10000, // 返回码,详见【4.3.2 公共响应参数】
msg: '成功', // * 返回码描述
sub_code: 'success', // 明细返回码
sub_msg: '', // * 明细返回码描述,显示给客户端用户【须语义化中文提示】,code不为10000时均需toast提示
sysMsg: '', // * 提示,调试使用,可包括中英文数字及特殊符号
result: [], // 返回的数据结果对象,可根据需要定义
page: {
current: 1, // * 当前页,从1开始 size: 10, // * 每页记录数 total: 100 // * 总记录数
}
},
message: '成功', // 提示,显示给客户端用户【须语义化中文提示】
sysMessage: 'success' // * 提示,调试使用,中英文都行
}
2.4 转义与编码
编码规则:encodeURIComponent 与 decodeURIComponent
URI特殊字符需转义
特殊字符及转义符号
特殊字符
转义后的符号
+
%2B
空格
%20
/
%2F
?
%3F
%
%25
#
%23
&
%26
=
%3D
!
%21
第三方回调页面URI需反转义,如:支付宝支付成功回调页面
URI汉字需转为Unicode码
2.5 加密
首选HTTPS,其中以下项目要求必须为HTTPS
APP
微信公众号和小程序
使用第三方API(如海康、高德等)
HTTP项目需要对关键敏感信息进行加密处理,HTTPS项目不做要求
账号、密码
账号、密码禁止明文传输,如admin等
密码加密策略:
方法一
服务器端存储密码为Hash(Random-Salt + Hash(Constant-SALT + Pasword))
客户端传输密码为Hash(Constant-SALT + Password)
Random-Salt为用户的随机盐,每个用户均不同,服务器端收到客户端的hash密码后,在将其与用户随机盐一起Hash运算,从而将结果与数据库存储值相比较。
优点:数据库存储的密码经过两层哈希,且其中包含了固定盐和用户随机盐,安全性较高。
缺点:客户端传输的密码虽然经过了一层哈希,但是使用固定盐值,因此相同密码生成的结果均一致,容易收到重放攻击。
方法二
服务器端存储密码为Hash(Constant-SALT + Pasword)
客户端传输密码为Hash(Random-Salt + Hash(Constant-SALT + Password))
Random-Salt为每次进入登陆页面时生成的随机盐,此处主要是为了防止重放攻击,作用类似与nonce 服务器收到客户端上传的hash之后的密码,根据用户ID取出服务器存储的密码,并通过与之前返回客户端的Random-Salt(可存储于Session中)进行Hash运算,从而与客户端上传的密码进行比较。
优点:客户端有效的防止了重放攻击。
缺点:在前端代码中,固定盐值暴露,一旦后台数据库被攻破,用户密码信息将有危险。
加密库:
MD5
crypto-js
手机号、银行卡号、姓名等私密信息
通用加密策略:
Hash(Constant-SALT + Pasword)
Random-Salt为每个应用or业务系统的随机盐,与其他细节加密字段进行Hash运算后再跳转。
数字加密策略:
转换进制,如:
// 加密
const mask = (+phone).toString(28)
// 解密
const phone = parseInt(mask, 28)
手机号、银行卡号加密策略:
方法一
参考上文数字加密策略
方法二
参考上文通用加密策略
姓名、邮箱、住址等加密策略:
参考上文通用加密策略
第三方跳转时URI加密
加解密策略
参考上文通用加密策略
2.6 跨域
CORS 实现
三、接口测试与模拟
3.1 工具:
RESTful
Swagger 这是最为接近上面理想模型的一个解决方案
JSON Server 快速生成JSON mock服务器
Easy Mock 可视化的、在线的接口mock服务
Yapi接口平台 支持本地部署
GraphQl
GraphQL Faker
graphql-tools
模拟数据生成
js 强大的模拟数据生成工具,支持Node和浏览器
js 数据生成和模拟工具
四、 附录
4.1 公共状态码(status)