不抽象:Increase API 设计原则
原文:Increase - 2024.04.26
(注:Increase 是一家提供金融技术服务的公司。)
API 资源是 API 的实体或对象。决定如何为这些实体命名和建模可以说是设计 API 最难也是最重要的部分。您所公开的资源组织了用户对您的产品如何工作以及它能做什么的心智模型。在 Increase,我们的团队采用了一项名为“不抽象”的原则来帮助我们。那么,这个原则是什么呢?
我们团队的大部分成员都来自 Stripe,在设计 API 时,我们考虑了在 Stripe 取得成功的相同价值观。Stripe 擅长在他们的 API 中进行抽象设计 —— 将复杂领域的基本特征提取出来,使用户能够轻松理解和操作。在他们的案例中,最显著的是将许多不同网络的支付建模到一个名为 PaymentIntent 的 API 资源中。例如,Visa 和 Mastercard 在发起退款的原因代码上存在细微差别,但 Stripe 将这些代码合并到一个枚举中,这样用户就不必分别考虑这两个支付网络。
这样做是有道理的,因为 Stripe 的许多用户都是早期创业公司,开发的产品与支付完全无关。他们不一定了解或需要了解信用卡的细微差别。他们希望快速集成 Stripe,继续开发自己的产品,而不再考虑支付问题。
“对 Increase 的用户来说,试图隐藏这些网络底层的复杂性会让他们感到烦恼,而不是简化他们的生活。”
Increase 的用户并非如此。他们通常对支付网络有深入的了解,一直在思考金融技术问题,之所以选择我们,是因为我们有直接的网络连接和深度集成,可以帮助他们构建支付网络。他们希望确切知道 FedACH 窗口何时关闭,转账何时到账。他们知道,在 ACH 转账上设置不同的 Standard Entry Class code 会导致不同的返回时间。试图隐藏这些网络的潜在复杂性(例如,通过单一 API 资源对 ACH 转账和电汇进行建模)会让他们感到烦恼,而不是简化他们的生活。
(注:ACH 是美国主要使用的电子支付系统。FedACH 则是美联储提供的 ACH 服务。)
与这些用户的早期对话帮助我们在构建第一版 API 时明确了“不抽象”原则。下面举例说明这种思维方式对 API 设计的影响:
现实的(Real-world)命名
我们倾向于使用底层网络的词汇,而不是自己为 API 资源及其属性命名。例如,在通过 Increase API 进行 ACH 转账时,我们公开的参数就是以 Nacha 规范中的字段命名的。
(注:Nacha 规范用于指导金融机构如何正确、安全地使用 ACH 网络进行电子交易。)
不可变性
与使用网络术语的方式类似,我们也尝试根据现实世界中的事件(如采取的行动或发送的消息)来为我们的资源建模。这使得我们更多的 API 资源是不可变的。对这种 API 来说,一种行之有效的方法是将这些不可变资源(例如,作为 ACH 转账生命周期的一部分可以发送的所有网络消息)集中起来,并将它们归类到一个状态机“生命周期对象”中。例如,我们 API 中的 ach_transfer
对象有一个名为 status
的字段,它会随着时间的推移而变化,还有几个不可变的子对象,会随着转账在其生命周期中的移动而被创建。一个新创建的 ach_transfer
对象看起来像这样:
{"id": "ach_transfer_abc123","created_at": "2024-04-24T00:00:00+00:00","amount": 1000,"status": "pending_approval","approval": null,"submission": null,"acknowledgement": null// 为了清晰起见,这里省略了其他字段
}
在同一笔转账通过我们的管道并提交给 FedACH 后,它看起来像这样:
{"id": "ach_transfer_abc123","created_at": "2024-04-24T00:00:00+00:00","amount": 1000,"status": "submitted",// 不可变的,当转账被批准时填充"approval": {"approved_by": "administrator@yourcompany.com","approved_at": "2024-04-24T01:00:00+00:00"},// 不可变的,当转账被提交时填充"submission": {"trace_number": "058349238292834","submitted_at": "2024-04-24T02:00:00+00:00"},// 不可变的,当转账被确认时填充"acknowledgement": {"acknowledged_at": "2024-04-24T03:00:00+00:00"}// 为了清晰起见,这里省略了其他字段
}
按用例分离资源
对于给定的 API 资源,如果用户可以在该资源的不同实例上执行的操作集差异很大,我们倾向于将其拆分为多个资源。例如,您可以对发起的 ACH 转账执行的操作集与接收的 ACH 转账执行的操作集不同(实际上完全相反),因此我们将其分为 ach_transfer
和 inbound_ach_transfer
资源。
这种方法可能会使我们的 API 更为冗长,乍看之下令人生畏–我们的文档页面左侧有很多资源!不过,我们认为从长远来看,这种方法更具有前瞻性和可预测性。
重要的是,我们的工程团队已经承诺采用这种方法。设计一个复杂的 API 需要数年的时间,这期间会不断做出小的增量决策。预先承诺“不抽象”原则减轻了这些决策的认知负担。例如,在向美联储发送电汇时,有一个名为Input Message Accountability Data 的必填字段,它是该电汇的全球唯一 ID。在构建支持电汇的功能时,API 抽象程度高的的工程师可能需要深思熟虑如何以“用户友好”的方式命名这个字段–trace_number
、reference_number
、id
…等等。在 Increase,这位假设的工程师会将字段命名为 input_message_accountability_data
,然后继续工作。当 Increase 的用户第一次遇到这个字段时,虽然一开始可能不是最容易识别的名称,但这可以帮助他们立即了解这个字段是如何映射到底层系统的。
“不抽象”原则并不适合每个 API,但考虑适合开发人员集成 API 的抽象程度是一项有价值的工作。这将取决于开发人员在您的产品领域的工作经验水平,以及他们为集成所投入的精力等。如果您正在构建一个抽象程度高的 API,那么在添加新功能之前,请深思熟虑。如果您要构建的是抽象程度低的 API,则应致力于此,并抵制在出现新功能时添加抽象功能的诱惑。
相关文章:
不抽象:Increase API 设计原则
原文:Increase - 2024.04.26 (注:Increase 是一家提供金融技术服务的公司。) API 资源是 API 的实体或对象。决定如何为这些实体命名和建模可以说是设计 API 最难也是最重要的部分。您所公开的资源组织了用户对您的产品如何工作…...
mybatis调用数据库存储过程
mybatis调用数据库存储过程及常见属性详解 调用mapper String visitCode mapper.getVisitCode(objectMap);Dao层,xml文件代码编写 <select id"getVisitCode" parameterType"map" resultType"string" statementType"CALLAB…...
【git】发生冲突后回滚提交
gerrit 冲突, 无法合并到主干 那么先回滚 参考这里的 reset 操作: 回滚 到上一个提交 $ git reset --soft HEAD~1 # 數字表示移動到 HEAD後面第幾個刚提交的会撤回, stash 刚刚提交的 然后去pull 最新的 修改冲突: 最后再…...
ISO14229 -1 UDS诊断服务记录-001:0x34\0x36\0x37\0x31\0x19\0x14服务报文格式介绍
目录 1、34服务-请求下载 1.1、诊断请求格式 1.2、正响应格式 1.3、负响应格式 1.4、工程应用分析 2、36服务-传输数据 2.1、请求报文格式 2.2、正响应格式 2.3、负响应NRC 3、37服务-退出传输 3.1、报文格式 3.2、正响应格式 3.3、负响应NRC 4、31服务-例程控制 …...
使用 MediaMTX 和 FFmpeg 推拉 RTSP 流媒体
实时流传输协议 RTSP(Real-Time Streaming Protocol)是 TCP/IP 协议体系中的一个应用层协议,由哥伦比亚大学、网景和 RealNetworks 公司提交的 IETF RFC 标准。该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP 在体系…...
Mac 电脑安装 Raptor 流程图软件的方法
0. 安装逻辑 (1)运行 raptor,本质上需要 mac 能够运行 windows 程序,因此需要安装 .NET Runtime 7.0,这是微软程序运行必须的文件。 (2)运行 raptor 还需要安装依赖文件 mono-libgdiplus。 &am…...
W801学习笔记二十:宋词学习应用
前三章完成了唐诗的应用,本章将实现宋词的学习应用。 宋词与唐诗的区别不大,马上开始。 1、我们需要参考前面唐诗的方式,把宋词文本下载下来,并进行格式整理。 W801学习笔记十七:古诗学习应用——上 2、在菜单中添加…...
EPAI手绘建模APP转换模型和坐标系
(11) 模型转换 图 273 转换工具栏 ① 实体转成曲面,先选择需要转成曲面的实体模型,再点击该按钮。将选择的实体模型转成多个曲面。 ② 曲线转成NURBS样条曲线,先选择需要转成NURBS样条曲线的边模型,修改转换参数,将选…...
STM32快速入门(串口传输之USART)
STM32快速入门(串口传输之USART) 前言 USART串口传输能实现信息在设备之间的点对点传输,支持单工、半双工、全全双工,一般是有三个引脚:TX、RX、SW_RX(共地)。不需要一根线来同步时钟。最大优…...
什么是网络安全和网络隐私?
什么是网络安全?这个是我最感兴趣的话题,网络安全说白了就是在网络上的安全,跟现实中一样,现实中为了家里的安全,我们会给家门上锁,会装监控,农村的话可能还会养一条狗,只有我们让别人进我们家,别人才能进来,对于计算机来说也是一样的,我们会设置账户的密码,会设置防火墙,会安…...
树莓派变小路由器放出热点wifi
环境 树莓派4Bubuntu20 作用 树莓派放出wifi后,笔记本电脑连接树莓派的wifi,并且ip配置在一个网段,就可以互相通信(笔记本放出wifi,树莓派连接效果一样),这样的好处是树莓派只要一上电就会自…...
数据猎手:使用Java和Apache HttpComponents库下载Facebook图像
引言 在信息驱动的时代,互联网上的数据成为了无可比拟的宝藏。本文旨在探讨如何通过利用Java和Apache HttpComponents库,从全球最大的社交网络平台Facebook上获取图像数据。 作为全球最大的社交网络平台,Facebook聚集了数以亿计的用户&#…...
uniapp——阻止冒泡
点击事件阻止冒泡 click.stop"onSubmit"其他类型,比如视频: 最后加了一个 click.stop <view class"videoBox" v-if"item.video_url"><video :src"i.image(item.video_url)" :controls"true&quo…...
Jmeter性能测试(四)
一、遇到问题解决思路 1、检查请求头是否正确 2、检查请求参数是否正确 3、检查鉴权信息是否正确 4、检查变量作用域 5、检查数据提取是否正确(正则/json提取器) 二、请求头检查 1、在Http信息头管理器查看 2、注意这里的变量作用域是全局的 三、请求参数检查 1、在查看结…...
从零开始精通RTSP之传输ADPCM等音频流
概述 在上一篇文章中,我们详细介绍了使用RTP传输AAC音频流的打包方法。除了AAC编码算法外,常用的音频编码算法还有ADPCM、G711A、G711U、G726等。接下来,我们继续介绍RTP传输ADPCM等音频流的打包方法。 封装方法 RTP封装ADPCM等音频数据时&am…...
box-decoration-break 使用介绍
box-decoration-break属性的使用 一、定义 box-decoration-break是CSS片段模块(CSS Fragmentation Module Level 3)中的一个属性,主要用于指定背景(background)、内边距(padding)、边框&#…...
技术分享 | 京东商品API接口|京东零售数据可视化平台产品实践与思考
导读 本次分享题目为京东零售数据可视化平台产品实践与思考。 主要包括以下四个部分: 1.京东API接口介绍 2. 平台产品能力介绍 3. 业务赋能案例分享 01 京东API接口介绍 02 平台产品能力介绍 1. 产品矩阵 数据可视化产品是一种利用数据分析和可视化技术&…...
OpenHarmony鸿蒙蓝牙BLE调试app
OpenHarmony蓝牙模块提供了ble的功能,本篇提供一个简单的app供测试时使用。代码使用API10,对应4.0Release版本固件。 1.开启BLE 开启BLE前,先在设置界面中打开蓝牙开关。 openBle()函数负责打开ble扫描,并打印扫描结果。主要代…...
HackMyVM-VivifyTech
目录 信息收集 arp nmap nikto whatweb WEB web信息收集 wpscan feroxbuster hydra 提权 系统信息收集 横向渗透 git提权 get root 信息收集 arp ┌──(root㉿0x00)-[~/HackMyVM] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 08:00:27:9d:6d:7b, …...
将unity中相机位置保存为json 文件或者 发送给后端
将unity中相机位置保存保存到服务器 ///相机的位置public Transform cameraTransform;void Start(){// SaveCameraPosition("sd");// ("{\"name\":\"sd\",\"position\":\"(0.00, 5.00, -12.00)\",\"rotation\&qu…...
vue2-表单组件封装
创建组件 components/test/index.vue <template><el-form :model"formData">// <!-- 具名插槽 --><slot name"header" /><el-form-itemv-for"(item, index) in formItem":key"index":label"item.la…...
智能家居4 -- 添加接收消息的初步处理
这一模块的思路和前面的语言控制模块很相似,差别只是调用TCP 去控制 废话少说,放码过来 增添/修改代码 receive_interface.c #include <pthread.h> #include <mqueue.h> #include <string.h> #include <errno.h> #include <…...
Python selenium
1.搭建环境 1.安装: pip install msedge-selenium-tools 不要使用pip install selenium,我的电脑上没法运行 2.下载驱动 Microsoft Edge WebDriver |Microsoft Edge 开发人员 edge浏览器点设置---关于即可找到版本号,一定要下载对应版…...
Python内置函数next()详解
Python的next()函数是一个内置函数,用于从迭代器中获取下一个元素。如果迭代器耗尽,则抛出StopIteration异常。 函数定义 next()函数的基本语法如下: next(iterator[, default])iterator:一个迭代器对象。default:可…...
初识指针(1)<C语言>
前言 指针是C语言中比较难的一部分,大部分同学对于此部分容易产生“畏难情结”,但是学习好这部分对C语言的深入很大的帮助,所以此篇主要以讲解指针基础为主。 指针概念 变量创建的本质就是在内存中申请空间,找到这个变量就需要地址…...
uniapp使用vconsole调试 兼容App
前言:引入vconsole发现uniapp打出来的包里,看不到vconsole,uniapp开发的h5需要使用vconsole真机调试,如果直接在main.ts引入,打包后整个项目会页面空白,经实验在单个页面引入可解决,以下是解决方…...
论文笔记模版
1. 摘要 1.1 背景 1.2 挑战 1.3 提出新方法 1.4 贡献 2. 引言 2.1 背景(引出问题) ①介绍大背景: ② 应用场景: ③ 介绍主题: 2.2 引出挑战 一般用图表来展现出我们的挑战(直观,解决什…...
docker-本地私有仓库、harbor私有仓库部署与管理
一、本地私有仓库: 1、本地私有仓库简介: docker本地仓库,存放镜像,本地的机器上传和下载,pull/push。 使用私有仓库有许多优点: 节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下…...
【Go 语言入门专栏】Go 语言的起源与发展
前言 Go 语言是当下最为流行的编程语言之一,大约在 2020、2021 年左右开始于国内盛行,许多大厂很早就将部分 Java 项目迁移到了 Go,足可看出其在性能方面的优越性。 相信各位都知道,在爬虫业务中,并发是一个关键的需…...
发电机组远程管理,提升管控力,降低运维成本
发电机组是指发电机发动机以及控制系统的总称,用来把发动机提供的动能转化为电能。它通常由动力系统、控制系统、消音系统、减震系统、排气系统组成。发电机组远程管理系统利用物联网技术与PLC远程控制模块集成解决方案,在提高发电机组的运行效率、降低运…...
制作网站需要注意什么/江苏网页设计
前言用过腾讯课堂的小伙伴们可能都知道,腾讯课堂播放时左右快进,后退的时候不太灵敏,有时候没反应,非常难受。我就想着能不能下载下来。在网上找了一圈都没有什么好用的方法。直到今天才找到方法,分享出来给大家使用。…...
网站制作优化济南/长春网站优化流程
写在前面 笔记内容大多出自于拉勾教育大前端高薪训练营的教程,因此也许会和其他文章雷同较多,请担待。 Yeoman $ npm i yo -g / $ yarn global add yo $ npm i generator-node -g / $ yarn global add generator-node // 基于node的开发脚手架&#x…...
国际网站怎么注册免费的/谷歌浏览器安卓版
接着上一篇在同一台服务器上配置app1.domain.com和app2.domain.com多个web应用,这里记录下在nginx下给express web app配置静态代理和文件压缩。目的 为了减少node.js对静态文件的处理和加快前端下载静态资源的速度,决定使用nginx做静态代理,…...
张家界简单的网站建设/百度服务中心人工客服
要运行java的项目需要先将项目打包成war包或者jar包,打包成war包需要将war包部署到tomcat服务器上才能运行。而打包成jar包可以直接使用java命令执行。 在linux系统中运行jar包主要有以下几种方式。 一、java -jar XXX.jar 这是最基本的jar包执行方式,…...
塔城地区建设工程信息网站/百度小说排行榜总榜
本文为大家分享了购物商城小程序,供大家参考,具体内容如下 软件版本:python3.x 功能:实现简单购物商城 1.允许用户选择购买多少件 2.允许多用户登录,下一次登录后,继续按上次的余额继续购买 3. 允许用户查看…...
网站平台优化/百度客服号码
第2课-数据的艺术 数据结构起源(1) 计算机从解决数值计算问题到解决生活中的问题。 (2) 现实生活中的问题涉及不同个体间的复杂联系。 (3) 需要在计算机程序中描述生活中个体间的。 数据结构主要研究非数值计算程序问题中的操作对象以及它们之间的关系。 关键概念(1…...