惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
博客园_首页
Microsoft Security Blog
Microsoft Security Blog
Blog — PlanetScale
Blog — PlanetScale
M
MIT News - Artificial intelligence
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
V
Visual Studio Blog
Jina AI
Jina AI
N
Netflix TechBlog - Medium
量子位
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
InfoQ
J
Java Code Geeks
T
Tailwind CSS Blog
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
阮一峰的网络日志
阮一峰的网络日志
Engineering at Meta
Engineering at Meta
腾讯CDC

Posts on WKLKEN THINKING

apisix 中的 lrucache apisix 中的服务发现机制 apisix 中的负载均衡 apisix etcd机制 聊聊框架 关于 k8s 的 zero downtime deployment 一些建议 apisix 遇到的一些问题 关于在除夕前一天换了一个洗衣机的故事 Django DRF 性能优化 DRF 的一些实践 Part1: Serializer DRF继承关系图 新的仓库: wklken/naming 缓存使用的一些经验 Better Code: 抽象: 可扩展性与可维护性的抉择 Better Code: 异常时, 该提示用户哪些信息? Better Code: 更好的异常日志打印 Go: some libs Go: go-redis/cache升级的坑 Go: logrus性能提升 Go: gin validation 远程办公的一点总结 Go: 开发过程中的一些bug 项目管理实践: 风险驱动开发 Go: 一种error wrap调用链处理方式 漫谈技术选型 Go: 基于 apitest 做handler层单元测试 Go: go-sql-driver interpolateparams参数优化 [分享]深度工作 你需要更多的思考时间 Django项目重构小结
Better Code: 关于接口的灵活性
2022-07-08 · via Posts on WKLKEN THINKING

在实际需求开发中,我们会面对复杂多变的需求。所以在给外部提供API的时候,经常会面临接口协议的变更:例如增加一个查询字段,支持按照某个字段升降序,或者多返回某个字段。

此时你也许会想,不如直接支持graphql或者类似的语法,将整个模型暴露出来,想要什么字段,根据什么排序,查询多少数据量,按照什么升降序自己决定好了。这样能做到一次开发,多次使用,一劳永逸。

但是,这往往是过于理想化的考虑,特别是对于大部分项目,或者被非常多外部系统依赖的服务(这也是为什么需求变更比较多的原因)


在实际开发中,我们都知道,一个接口一旦上线生产,那么协议变更就变得非常难,至少要非常谨慎。因为有众多的依赖方。并且下线一个接口也尤为困难,因为势必要推动所有系统切换新接口。

所以,如果暴露整个模型由调用方自行选择,那么结果就是,将主动权交给了调用方,把自己变得被动。因为你很难感知到调用方是如何组合那些条件的,用了哪些参数,是否合理。模型层面的变更将变得困难,字段的增删,类型变更,格式变更等等都需要考虑诸多调用方。

相当于拿一时的便利,换取了未来维护的不确定性。但是,确定的是,维护成本是成倍地上升。


假设模型数据变得庞大,从几千增长为十万级,百万级,那么原先很多无关紧要条件变得棘手,例如按照一个不确定的字段排序,或者一个不在索引中的字段排序。此时原先的查询变得很慢,数据库压力变大,机器负载上升。

那么,这时候要保证系统正常,就会付出更大的代价。

这个可不是提供一个/api/v2那么简单,大部分系统一旦使用,除非特别的原因,否则是不会考虑迁移新接口的,此时,可能由于某几个很小的系统调用吃掉系统绝大部份的资源。举步维艰。

所以,在接口协议设计和提供的时候,需要花更多的时间去思考,始终保持谨慎克制

比如,需要一个字段,绝不提供两个。协议中可选的内容,都是已确认可控的内容。消除不确定性。

这或许看起来接口不够灵活,不够强大。但是,消除了不确定性。


应该在内部实现保持灵活,但暴露出去的保持克制。例如某些地方可以变成可配置的,需求变更只需要改配置而不是代码。

即,灵活性始终把握在自己手中。应对需求变更的时候,付出少量的时间。相对原先绝对灵活的方式会多出一些确认及开发的时间,但是对于未来的维护时间,这已经是非常划算的了。

内部支持,谨慎提供。 make everything under control

如果调用方可控,例如前后分离自己的前端或者同一个系统内的上层服务,那么用graphql 或者类似灵活的方式提供接口问题不大,毕竟变更或升级的成本不高,比较可控。

否则,提供接口不要那么奔放。


另外,最近遇到一个问题得到一个小的tip,如果一个接口需要提供两种或两种以上有差异的返回(协议有差别,但是不是特别大),建议提供多个接口而不是在一个接口通过参数动态确定返回。即使差异非常小。差异小只在当下,随着时间推移需求变化,耦合在一起的代码将会维护困难,改一个逻辑可能动到不相关的返回。宁可多写一些代码,尽量保持逻辑独立性。