不抽象:Increase API 设计原则

news2024/12/23 15:21:28

在这里插入图片描述

原文: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_transferinbound_ach_transfer 资源。


这种方法可能会使我们的 API 更为冗长,乍看之下令人生畏–我们的文档页面左侧有很多资源!不过,我们认为从长远来看,这种方法更具有前瞻性和可预测性。

重要的是,我们的工程团队已经承诺采用这种方法。设计一个复杂的 API 需要数年的时间,这期间会不断做出小的增量决策。预先承诺“不抽象”原则减轻了这些决策的认知负担。例如,在向美联储发送电汇时,有一个名为Input Message Accountability Data 的必填字段,它是该电汇的全球唯一 ID。在构建支持电汇的功能时,API 抽象程度高的的工程师可能需要深思熟虑如何以“用户友好”的方式命名这个字段–trace_numberreference_numberid…等等。在 Increase,这位假设的工程师会将字段命名为 input_message_accountability_data,然后继续工作。当 Increase 的用户第一次遇到这个字段时,虽然一开始可能不是最容易识别的名称,但这可以帮助他们立即了解这个字段是如何映射到底层系统的。

“不抽象”原则并不适合每个 API,但考虑适合开发人员集成 API 的抽象程度是一项有价值的工作。这将取决于开发人员在您的产品领域的工作经验水平,以及他们为集成所投入的精力等。如果您正在构建一个抽象程度高的 API,那么在添加新功能之前,请深思熟虑。如果您要构建的是抽象程度低的 API,则应致力于此,并抵制在出现新功能时添加抽象功能的诱惑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1655559.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么才是正确的领域驱动实现架构?

作为一种系统建模方法,DDD同样涉及系统的体系架构设计。区别于分布式、事件驱动、消息总线等架构设计方法,DDD中的架构设计关注前面各章所介绍的聚合、实体、值对象、领域事件、应用服务以及资源库之间的交互方式和风格,并在设计思想上有其独…

揭秘设计师必备神器:情绪板是什么?

每个伟大的设计项目都从一点灵感开始。无论你是在设计网站、应用程序,还是想重新装修房子,情绪板都可以帮助你激发创造力,甚至情绪板也可以决定UI界面是否成功。本文将分享什么是情绪板,为什么需要情绪板,以及如何充分…

Linux下多线程相关概念

thread 1.什么是线程1.1 线程优缺点1.2 线程异常1.3 线程用途 2. 进程和线程区别3. 线程控制3.1 POSIX线程库3.2 pthread_create()3.3 线程ID3.4 线程ID地址空间布局pthread_self() 3.5 线程终止pthread_exit函数pthread_cancle函数 3.6 线程等待3.7 分离线程__thread修饰全局变…

OpenCV Radon变换探测直线(拉东变换)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 Radon变换可以将原始图像中直线特征的处理问题转化为变换域图像中对应点特征的处理问题,其中对应特征点的横坐标表示原始图像的旋转角度,一般来讲原始图像中的噪声不会分布在直线的特征上。因此,Radon变换在探测…

Python实战开发及案例分析(12)—— 模拟退火算法

模拟退火算法(Simulated Annealing)是一种概率搜索算法,源自于金属退火过程。在金属退火中,通过缓慢降低温度,金属内部的原子能够从高能态逐步达到较低能态。模拟退火算法利用类似的原理,通过随机搜索和概率…

吉时利2400与Keithley 2450 SMU 数字源表区别?

Keithley SMU(源测量单元)数字源表是一种精密的电子测试设备,它结合了电流和电压源以及测量功能。这些设备被设计用于需要紧密耦合源和测量的测试应用中。Keithley 2400系列SMU数字源表提供了四象限精密电压和电流源/负载,以及触摸…

远程智控BACnet/IP I/O模块助力Metasys系统无缝对接

江森自控的Metasys系统以其强大的综合管理能力成为众多楼宇自控项目的首选平台。然而,面对日益增长的个性化需求与复杂多变的设备接入挑战,如何高效、灵活地扩展其I/O控制能力成为关键。在此背景下,BACnet/IP分布式远程I/O模块的出现&#xf…

可视化大屏的应用:电子政务领域的巨大应用价值

可视化大屏在电子政务领域的应用价值主要体现在以下几个方面: 数据监控与分析 可视化大屏可以将政务数据以图表、地图等形式展示在大屏上,帮助政府部门实时监控和分析各项指标和数据变化。例如,可以实时显示人口统计、经济指标、环境监测等…

如何评估大模型音频理解能力-从Gemini说起

Gemini家族包含Ultra、Pro和Nano三种大小的模型是谷歌开发的大型多模态人工智能模型,它在人工智能的多模态领域实现了重大突破,结合了语言、图像、音频和视频的理解能力。 Gemini的性能评估情况如下: Gemini模型的评估的具体指标从文本理解能…

专题六_模拟(1)

目录 1576. 替换所有的问号 解析 题解 495. 提莫攻击 解析 题解 1576. 替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 解析 题解 class Solution { public:string modifyString(string s) {// 40.专题六_模拟_替换所有的问号_Cint n s.…

Qt跨平台开发demo(适用萌新)

最近需要参与一款Qt跨平台的软件开发,在此之前,特把基础信息做学习和梳理,仅供参考。 所使用的技术和版本情况如下: 虚拟机:VMware 16.2.5操作系统:ubuntu-20.04.6-desktop-amd64:Mysql数据库…

在阿里云K8S容器中,部署websocket应用程序的总结

一、背景 有一个websocket应用程序,使用spring boot框架开发,http端口号是6005,提供的是websocket服务,所以它还监听一个8889端口的tcp协议。 现在要把它部署到阿里云的k8s容器里,本文着重描述service层的配置。 因…

不会pdf修改编辑文字怎么办?看完秒懂

不会pdf修改编辑文字怎么办?在日常生活中,PDF文件已成为我们工作、学习不可或缺的一部分。然而,很多人对PDF文件的编辑操作感到困惑,尤其是修改其中的文字。今天,我们就来详细解析一下,不会PDF修改编辑文字…

C++进阶之路:探索访问限定符、封装与this指针的奥秘(类与对象_上篇)

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

鸿蒙开发之 if/else:条件渲染

ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用if、else和else if渲染对应状态下的UI内容。 使用规则 支持if、else和else if语句。if、else if后跟随的条件语句可以使用状态变量。允许在容器组件内使用,通过条件渲染语句构建不同的子…

数据结构--图。

在前面,我们学习了线性表和树,而接下来我们要学习的图相较于他们就更加复杂。 目录 一.图的有关概念 一.图的有关概念 1.定义 图(graph)G由两个集合V和E组成,记为G(VE)。V是顶点的有穷非空集合;E是边的集合,边是V中顶点的无序对…

02-单片机商业项目编程,从零搭建低功耗系统设计

一、本文内容 上一节《01-单片机商业项目编程,从零搭建低功耗系统设计-CSDN博客》已经对事件驱动原理有个基本了解,本节主要就是如何将事件写的更规范,而不是用t_flag这样的标记,写多了可读性也不强;本节结尾总结将提出…

【探索Java编程:从入门到入狱】Day5

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收…

《ESP8266通信指南》13-Lua 简单入门(打印数据)

往期 《ESP8266通信指南》12-Lua 固件烧录-CSDN博客 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP8266通信指南》10-MQTT通信(Arduino开发)-CSDN博客 《ESP8266通信指南》9-TCP通信(Arudino开发)-CSDN博客 《ESP82…

驱动比例线圈功率放大器

驱动比例线圈功率放大器是一种用于控制比例电磁铁的电流大小实现被控设备的位移,采用高性能的嵌入式32位微处理器作为运算核心,这些微处理器具有高速指令运行能力,电源24VDC驱动,输入指令兼容性强,输出电流大小可调&am…