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

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
The Register - Security
The Register - Security
S
Secure Thoughts
有赞技术团队
有赞技术团队
Hacker News - Newest:
Hacker News - Newest: "LLM"
月光博客
月光博客
Engineering at Meta
Engineering at Meta
www.infosecurity-magazine.com
www.infosecurity-magazine.com
WordPress大学
WordPress大学
N
News | PayPal Newsroom
F
Fortinet All Blogs
Forbes - Security
Forbes - Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Y
Y Combinator Blog
L
LINUX DO - 最新话题
Google Online Security Blog
Google Online Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
阮一峰的网络日志
阮一峰的网络日志
Application and Cybersecurity Blog
Application and Cybersecurity Blog
V2EX - 技术
V2EX - 技术
H
Heimdal Security Blog
G
Google Developers Blog
Vercel News
Vercel News
Martin Fowler
Martin Fowler
TaoSecurity Blog
TaoSecurity Blog
腾讯CDC
Cyberwarzone
Cyberwarzone
罗磊的独立博客
S
Securelist
T
Tor Project blog
Recorded Future
Recorded Future
小众软件
小众软件
Attack and Defense Labs
Attack and Defense Labs
L
LINUX DO - 热门话题
The Cloudflare Blog
爱范儿
爱范儿
S
Security @ Cisco Blogs
雷峰网
雷峰网
Schneier on Security
Schneier on Security
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
S
Schneier on Security
大猫的无限游戏
大猫的无限游戏
Recent Announcements
Recent Announcements
Blog — PlanetScale
Blog — PlanetScale
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Latest news
Latest news
M
MIT News - Artificial intelligence

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项目重构小结 工作七年小结: 学习,生活及其他 [分享]bash日常: bash-utils 极客时间推广海报 2017总结: 予时光以意义 k8s APIServer源码: api注册详细细节 k8s APIServer源码: api注册主体流程 k8s APIServer源码: 服务启动 k8s APIServer源码: go-restful框架 重构 - 读书笔记(Python示例) 写给新人的沟通建议 vim 杂谈 - 关于快速编辑 vim 杂谈 - 关于移动 读书笔记-重构: 章11 处理概括关系 读书笔记-重构: 章10 简化函数调用 读书笔记-重构: 章9 简化表达式 读书笔记-重构: 章8 重新组织数据 读书笔记-重构: 章7 在对象之间搬移特性 读书笔记-重构: 章6 重新组织函数 Python 代码规范小结 [分享]关于vim ElasticSearch集群部署文档 Logstash+ElasticSearch处理mysql慢查询日志 [分享]关于代码调试DE那些事 Logstash+ElasticSearch+Kibana- 实现相对通用的数据收集分析 ELK维护的一些点(二) [分享]Python源码剖析-数据结构 一些Centos Python生产环境的部署命令 摘录<<6个月学会任何一种外语>> ELK 维护的一些点 也许是一个新的开始 一些vim的个性化配置 读书笔记-调试九法 这段时间的一些想法 Python 源码阅读 - 垃圾回收机制 我为什么要写博客 APUE笔记-第一章 UNIX基础知识 Python源码阅读-闭包的实现 Python源码阅读-内存管理机制(二) Python源码阅读-内存管理机制(一) Python-基础-数据结构小结 '活动'设计的一些trick 一些简单的Python测试题 我的tmux配置及说明【k-tmux】 Review and Restart 工作四周年小结 vim插件: surround & repeat[成对符号编辑] vim插件: gundo[时光机] vim插件: expand-region[区域选中] vim插件: quickrun[快速执行] vim插件: trailing-whitespace[行尾空格处理] vim插件: closetag[成对标签补全] vim插件: ctrlp[文件搜索] vim插件: airline[状态栏增强] vim插件: theme[主题] vim插件: tagbar[大纲式导航] vim插件: nerdcommenter[快速注释] vim插件: rainbow_parentheses[括号高亮] vim插件: syntastic[语法检查] vim插件: delimitmate[符号自动补全] vim插件: matchit[成对标签跳转] vim插件: easy-align[快速对齐] vim插件: multiple-cursors[多光标操作] vim插件: vim-signature[快速标记跳转] vim插件: easymotion[快速跳转] vim插件: vundle[管理插件] Elasticsearch几个问题的解决 分享一份 Vim 简介PPT k-vim 更新9.0版本 关于知识管理工具的思考 Logstash+ElasticSearch+Kibana处理nginx访问日志
Better Code: 关于接口的灵活性
2022-07-08 · via Posts on WKLKEN THINKING

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

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

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


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

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

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


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

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

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

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

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

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


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

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

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

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

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


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