当前位置: 首页 > news >正文

在繁杂的业务需求中,如何找到API设计的平衡点

这是学习笔记的第 2150 篇文章


640?wx_fmt=gif

  关于API设计,有什么好的设计方法,或者说如何来构建一个相对健壮的后端API设计体系?我觉得还是在不断的实践中犯低级错误逐步积累起来的,或者是到了不得不改的时候才会造成这种变革和重构的过程。 

  比如说现在服务的后端有20个接口,基本人为还可以做好基本的配置管理。而一旦接入了业务流程,很多对象实体(模型)层产生了状态交互,那么这个复杂度就会高很多,而在逻辑实现或者API逻辑实现中,这块就很容易产生一个问题,那就是不断打补丁。

   比如A的状态变更,会导致B状态变更,B的状态变更会导致C状态变更,在程序里面就需要不断的调整,添加逻辑。如果这样的关系越来越复杂,人为是很难统一管理起来的,基本上就处于崩溃的边缘,疲于应付,一种就是增加无穷无尽的API,满足业务需求,成为典型的密集型,另一种情况就是修正无穷无尽的业务逻辑问题,成为一团乱麻。 

   我们目前的情况没这么糟糕,但是从扩大的业务需求和维护管理来看,已经逐步显示出不少问题。

    那么回过头来,我们来想一个本源的问题?

    什么样的API设计是好的设计,公认的一种实现就是File API 的主要接口(以C为例,很多是 Posix API,选用比较简单的I/O接口为例

  1. int open(const char *path, int oflag, .../*,mode_t mode */);

  2. int close (int filedes);

  3. int remove( const char *fname );

  4. ssize_t write(int fildes, const void *buf, size_t nbyte);

  5. ssize_t read(int fildes, void *buf, size_t nbyte);

为什么File API 是经典的好 API 设计?

  • File API 已经有几十年历史(从1988年算起,已30年),尽管期间硬件软件系统的发展经历了好几代,这套 API 核心保持了稳定。

  • API 提供了非常清晰的概念模型,每个人都能够很快理解这套API背后的基础概念:什么是文件,以及相关联的操作(open, close, read, write),清晰明了;

  • 支持很多的不同文件系统实现,这些系统实现甚至于属于类型非常不同的设备,例如磁盘、块设备、管道(pipe)、共享内存、网络、终端 terminal 等等。这些设备有的是随机访问的,有的只支持顺序访问;有的是持久化的有的则不是。然而所有不同的设备不同的文件系统实现都可以采用了同样的接口,使得上层系统不必关注底层实现的不同,这是这套 API 强大的生命力的表现。

我来总结下在API设计中自己感悟的一些小技巧,比如我们对于业务开放接口,不希望有20个功能,开放20个不同的接口,可能对于业务来说,我开放一个接口或者少数几个接口就行,而对于参数等可以根据不同的逻辑场景有所差别,比如下面的API,有一个统一的访问入口,比如是v1/api/user_info

对于这个API下面我们可以定义一系列的相关接口,可以通过不同的code来定义区别。 

640?wx_fmt=png

另一个层面来看,我们设计的Model或者Object实体,其实从数据模型层设计来看,无非就是对于数据对象的增删改查操作,而这些增删改查操作也会随着实体的属性复杂度情况而提供相应的方法。

640?wx_fmt=png

对于业务访问来说,其实是希望从业务视角来进行抽象,比如创建用户,修改用户资料,销户等操作,都是在业务层面来定义的,随着这些变化,会涉及相关的对象实体变化,而这样基于流程的变更也更贴近业务场景。

640?wx_fmt=png

所以整个逻辑串联起来就会是下面这样的流程,而在这个过程中我们需要对已有的model层面进行细化的设计,对于model层面的增删改查属于内部的API,而对接业务层的则是FlowControl部分的API,他们有着不同的定位和权限隔离,比如对外业务我们不能提供Model层的增删改查接口,而需要统一交由流程层来进行对接。

640?wx_fmt=png

小结:

在需求不清晰,管理混乱之中,需要找到工作的平衡,而需要更持久有效的管理,和这些管理设计是分不开的。

近期热文:

相关文章:

  • Greenplum的segment故障自愈小试
  • MySQL表添加了一个字段,竟然导致数据无法写入,反思
  • 通过Maxwell解析MySQL Binlog,打好业务多活的基础
  • 快到买买买的日子了,对于买书我提几点建议
  • 深度解读:我为什么从来不过“双十一”
  • 《黑客与画家》经典语录
  • 一个MySQL服务CPU 100%的优化案例反思
  • MySQL双主模式下是如何避免数据回环冲突的
  • MySQL中的SQL优化建议那么多,该如何有的放矢
  • dbaplus广州站归来
  • 梳理这件事情做不好,很多努力都是白费
  • 怎么证明根号2是无理数,我们来推导和计算,还有逼格极高的算法
  • 行锁:InnoDB 替代 MyISAM 的重要原因
  • 数据双向复制中的6个数据冲突场景和解决思路
  • MySQL多活数据消费服务设计方案
  • ES6--对象的扩展
  • exports和module.exports
  • HTTP--网络协议分层,http历史(二)
  • JavaScript的使用你知道几种?(上)
  • Java超时控制的实现
  • Magento 1.x 中文订单打印乱码
  • MySQL数据库运维之数据恢复
  • PHP变量
  • QQ浏览器x5内核的兼容性问题
  • vue-cli3搭建项目
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 对超线程几个不同角度的解释
  • 普通函数和构造函数的区别
  • 实现菜单下拉伸展折叠效果demo
  • 怎么把视频里的音乐提取出来
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • raise 与 raise ... from 的区别
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • # Java NIO(一)FileChannel
  • #NOIP 2014# day.1 T2 联合权值
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (007)XHTML文档之标题——h1~h6
  • (1)虚拟机的安装与使用,linux系统安装
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (图)IntelliTrace Tools 跟踪云端程序
  • (转)linux下的时间函数使用
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .net对接阿里云CSB服务
  • .net与java建立WebService再互相调用
  • @31省区市高考时间表来了,祝考试成功
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • @serverendpoint注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • [BetterExplained]书写是为了更好的思考(转载)
  • [C++核心编程](四):类和对象——封装
  • [codeforces]Checkpoints