自己做接口开发的时间也算不短了(三年),想写这篇文章其实差不多已经有一年多的时间了。我将从下面的方向来对我所理解的接口设计做个总结:
接口参数定义 -> 接口版本化的问题 -> 接口的安全性 -> 接口的代码设计 -> 接口的可读性 -> 接口文档 -> 我遇到的坑
接口设计中往可以抽象出一些新的公共参数,从事了近三年的接口开发工作中,我目前能想到了一些较为常见的公共接口参数如下:
公共参数 | 含意 | 定义该参数的意义 |
---|---|---|
timestamp | 毫秒级时间戳 | 1.客户端的请求时间标示 2.后端可以做请求过期验证 3.该参数参与签名算法增加签名的唯一性 |
app_key | 签名公钥 | 签名算法的公钥,后端通过公钥可以得到对应的私钥 |
sign | 接口签名 | 通过请求的参数和定义好的签名算法生成接口签名,作用防止中间人篡改请求参数 |
did | 设备ID | 设备的唯一标示,生成规则例如android的mac地址的md5和ios曾今udid(目前无法获取)的md5, 1:数据收集 2.便于问题追踪 3.消息推送标示 |
接口设计中有个算是历史上的难题 -> 接口版本化。曾经也去调研了很多关于接口版本化的资料和设计,最后我得到的结论大致如下:
接口的安全性
接口的设计肯定绕不开安全这两个字,为了达到尽可能的安全,我们需要尽可能的增加被攻击的难度,以下是我了解和使用到的一些常见的手段去增加接口的安全性(https这里就不讨论了):
过期验证/签名验证/重放攻击/限流/转义
伪代码如下:
接口的代码设计 -> 解耦业务 即插即用
这个过程的关键字:抽象成类 前置中间件 注入
接着就是我们代码设计的层面了,如何抽象公共的部分与业务代码解耦。一般写法, 定义个全局函数,然后每个接口开始时调用该函数:
二般写法, 定义个父类方法,然后每个接口类继承该接口,构造函数调用改方法,其实和上面的换汤不换药:
重点来了,我提倡的第三般写法,对象链和前置中间件:
接口的可读性
关于可读性的不得不提到的就是RESTFUL,这里我就不讨论RESTFUL,大家可以自行补充相关知识。关于接口设计可读性的我的一些思考:
接口文档
好的接口文档就是生产力, swagger + api blueprint 自行google吧?
我遇到的坑
这里遇到的一个比较大的坑就是http协议历史遗留的bug:
不区分url里的空格 和加号➕
带来的问题就是urldecode会把参数里的+号转为空格,所以这种场景的就得使用rawurldecode防止+转成空格。比如做接口的参数校验的时候~