写点什么

架构误区系列 19:Big API

作者:agnostic
  • 2024-02-16
    上海
  • 本文字数:1305 字

    阅读完需:约 4 分钟

在上个世纪设计的一些系统里面,往往喜欢和设计 TCP/UDP 协议一样,把一个接口设计的非常通用。不管是创建、修改还是查询,不管是什么类型的单据,都用一个接口来支撑。通过接口中的某几个字段,甚至接口中的某几位(例如 FIX 的设计)来区分单据类型和动作。


这种“BIG API”模式的接口设计,是 legacy 系统通过 TCP 报文进行系统间交互的遗留。在通过 TCP 报文进行通讯的时代,往往是通过报文的字节流来定义不同的服务。但是在现在进入面向服务的时代后,这种设计就显得有些落伍了。


目前的 API,一般的通讯协议是 HTTP,编码通常采用 json 或 XML。在这种文本化的接口设计下,已经没必要定义一个大的报文结构,可以根据不同的场景分别定义相应的服务接口。


大接口的方式,存在如下的不足:

  • 接口的定义会非常复杂,可能一个接口就需要几十页的说明文档,可读性非常差。沟通和联调都会非常痛苦。

  • 接口的实现也会非常复杂。在移动互联网时代,往往一个接口需要同时维护向下兼容的多个版本。type+action+version,这样多个组合的笛卡尔积,想想都是一个开发的噩梦。

  • 接口的测试也会非常困难。一个改动点,可能就需要对所有相关的功能进行回归。

  • 在架构上,隔离性也不可能做的很好。不管内部的 dispatcher 设计的怎么优雅,实现的多美优美。由于本质上是一个大的接口,或多或少总有一些隔离不清楚的点。

  • 在这种设计的理念下,往往开发人员对于新增功能,会不自觉的考虑不改变现有模型,复用已有的字段,用扩展字段的方式来实现,最终各种扩展各种兼容,无法传承。


在移动互联网时代,在服务化架构下,对于 API 的设计,我们应该遵循如下原则:

  • 不同的场景绝对的隔离。比如,远期交易和即期交易,就应该是两套完全不同的服务。虽然两者都有询价的服务,但是远期有 tenor 概念,有 flexible 概念,有保证金,相对于即期会复杂很多,虽然看似业务语意是类似的,但也没必要“复用”。

  • 不同的动作应该定义不同的接口。参照 Restful 的设计,创建、修改、查询和删除(失效)应该是四个不同的服务。特别的,写服务和读服务,如果两者的 SLA 差别比较大的话,内部的实现逻辑也应该分开,遵循 CQRS 的原则。

  • 不同的版本建议定义不同的接口。这点上可能会有比较大的争议。一般大家对于不同的版本一般都考虑在同一个接口中用版本号来区分,版本和版本之间需要做到向下兼容。但是就是这个向下兼容,大家想一想如果是针对移动端的服务,不同代际的移动设备的性能和设计理念差别很大,这个向下兼容能做的多好呢?不如将接口就分开,能兼容兼容,不同兼容就不兼容。只需要保证内部的模型是一份或者可以兼容可以向上迁移就可以。


这样的服务设计,相对于 Big API,有如下的好处:

  • 概念清晰:不同的场景用不同的服务组来承载,在文档、联调、维护上都会相对比较简洁。

  • 隔离性好:不同场景之间不会有共用的接口。场景和场景之间隔离性好,不会相互影响。

  • 开发便捷:设计和开发人员只需要专注在自己负责的场景,范围小了,效率自然就提高了。

  • 测试方便:只需回归特定场景,可以极大的提升测试效率。

  • 杜绝“弹性字段”的诱惑:由于服务支撑的场景确定,服务的定义会很好的映射相应的领域模型,没必要加入各类的弹性字段,可以杜绝由于这些字段的含义模糊导致的问题,提升服务质量。


发布于: 刚刚阅读数: 3
用户头像

agnostic

关注

常识、KISS、高可用、合规架构、架构治理 2019-02-14 加入

二十年架构经验,互联网金融专业架构师。Open Group Master Certified Architect

评论

发布
暂无评论
架构误区系列19:Big API_agnostic_InfoQ写作社区