接口设计与联调经验
不同系统之间存取数据,技术上最简单的方式就是提供接口。既然是不同系统,那么大家很可能不是同一家单位,需要留意的事情也会更多。本文记录了一些接口设计、联调前后需要考虑的事情。总体上来讲,我们既要保证准确实现功能,又要留个心眼,保护自己的利益,避免让自己吃亏。
设计
虽然接口的原理很简单,开发工作量可能也比其他开发工作少很多,但是需要留意,在业务问题上“我这样想”不代表“对方也会这样想”,并且开发时的沟通成本往往会比较高,上线之后一旦出现故障可能还会互相踢皮球,因此也不能把设计工作想象得太简单。
- 约定好具体的数据格式、字符编码和收发方式!例如“传JSON”既可能是直接HTTP POST一段JSON(application/json),也可能是调用WebService,里面参数为JSON(application/xml),前者通常是在用户浏览器上通过AJAX调用,后者可能是自己后台直接调用对方的服务器,不经过用户的界面。如果连这个都弄错,后续发现问题时就要全部推倒重来了;
- 确保双方对于每个函数、每个参数的理解是一致的。特别是业务系统,对方对业务场景与业务的理解可能与我们很不一样,因此要多进行确认,及时更新和完善文档;
- 接口定义要慎重,因为调整定义的成本比调整实现的成本高得多,而且接口定义和值域不要定得太死(即使是性别也不一定只有男、女和其他),要有能够调整和扩展的空间;
- 搞清楚接口调用时机、频率,估计一下接口调用数据规模,避免因为频率不当或者数据规模太大而出问题;
- 有异常处理和超时机制,能够正确处理目标服务器宕机、404、500、长时间不返回等情况。接口恢复后,故障期间产生的数据能够正确消化掉;
- 检查输入数据是否合法(格式正确、符合业务要求以及具有业务权限),拒绝格式不合规范的数据,避免出现类似用户改个ID就能查看或修改别人数据的情况;
- 对于有状态的数据,约定好重复发送请求(例如用户或程序重复提交工作单)的后果;
- 考虑专门的日志记录,例如使用专门的文件或在数据库建立接口日志表;
- 有认证机制和访问控制机制,防止接口被无关厂商及人员冒用或恶意调用。
联调
联调最大的问题就是沟通成本,因为沟通成本高所以容易积攒问题,因此建议:
- 不定期组织交流,有条件当面聊的话最好当面聊,没有条件的话也要有语音视频会议,避免纯文字交流,免得越做偏差越大;
- 早联调、多联调,早点暴露问题,不要等一切都准备好之后才开始调;
- 有条件的话准备一个能够随时调用的环境(当然也要有配套的测试数据)。
如果是不同公司之间进行合作,不要忘记留证据,具体而言:
- 记录哪天、与哪个人、调试了什么东西、结果如何;
- 各接口函数要输出日志,记录时间、原始数据和一些关键数据;
- 重要内容留截图。
推荐两个调试接口的软件,一个是专门测WebService的SoapUI,另一个是可以测各种请求的Postman。对我个人而言,由于我们项目经常是WebService里面套JSON,所以SoapUI用得并不舒服,不如自己抓到调用WebService的原始请求内容然后全部扔到Postman中调试:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:xxxxxmethod xmlns:ns1="http://service.xxx.xxxcompany.com/">
<arg0>
{
"param1": "xxx",
"param2": "yyy",
...
}
</arg0>
</ns1:xxxxxmethod>
</soap:Body>
</soap:Envelope>
如果主要系统已经上线了,注意不要在生产环境或使用生产库直接联调,而是要准备一个和生产环境架构相似的测试环境,在测试环境上进行联调。在生产环境和生产库上,双方顶多测一下接口和功能通没通,不要测别的东西。
运行
上线之后更要专门记录接口的调用情况,做到有据可查。清楚地了解接口调用情况、频率以及状态,在出现故障时可以尽量避免踢皮球和承担无谓责任。有必要的话还应该实行访问控制,一旦遭遇攻击或疑似攻击(例如调用频率太高等)时可以方便地进行处理。
运行之后,假如要对接口进行重大调整,那么要确保向后兼容,除非非常确定大家不会再使用旧版定义了。
补充技巧
甩锅
我们系统有一个接口经常出问题,责任经常在对方,但是用户总给我们客服打电话,而且对方公司经常消极对待,于是我一怒之下把对方公司的名字和客服电话写到展示给用户的错误信息里面了。
勇于承担责任是男人,但在职场上勇于承担责任可不会被夸,所以只要不是自己责任,该甩的锅就得甩掉。
内网穿透
理想情况下应该建立一个双方都便于访问的开发测试区。如果没有条件或者来不及准备,而且双方公司都能访问互联网,可以通过内网穿透的方法把本地应用映射到公网上。
操作步骤参见此处。