API 设计的原则

2023-06-03 0 448

API 本身的涵义指应用领域开发工具,包括所倚赖的库、平台、操作形式控制系统提供更多的潜能都可以叫作 API。他们在讨论微服务项目情景下的 API 结构设计都是指 WEB API,一般的实现有 RESTful、RPC等。API 代表者了两个微服务项目示例对外提供更多的潜能,因而 API 的数据传输文件格式(XML、JSON)对他们在结构设计 API 时的负面影响并不大。

API 结构设计时微服务项目结构设计中非常重要的各个环节,代表者服务项目间可视化的形式,会负面影响服务项目之间的软件系统。 通常来说,两个好的 API 结构设计须要满足两个主要的目的:

输文件格式不如果入侵到销售业务方法论中,也就是控制系统如果具备即时支持不同数据传输协定和消息文件格式的潜能。Hardoi。 在 API 已经被发布和非 API 版改变的情况下,API 如果对契约书负责,不如果导致数据文件格式发生破坏力的修正。在 API 须要重大预览时,采用回退的形式修正,并对旧版留出推向市场时间询问处。

API 结构设计的准则

实践中发现,API 结构设计是一件极难的事情,同时也极难来衡量结构设计是否杰出。依照控制系统结构设计和消费者的角度,得出了许多单纯的结构设计准则。

采用适用性最合适的 RESTful API

RESTful 艺术风格的 API 具备许多纯天然的优势,比如透过 HTTP 协定降低了应用程序的谐振,具备极佳的发展性。因而越来越多的开发人员采用 RESTful 这种艺术风格结构设计 API,但是 RESTful 只能称得上两个结构设计思想或经营理念,不是两个 API 规范化,没有许多具体内容的不动点。

因而在结构设计 RESTful 艺术风格的 API 时候,须要参照 RESTful 适用性数学模型。

适用性级别解释示例Level 0表述两个根 URI,所有的操作形式透过 POST 允诺完成POST /?action=changeUserPasswordLevel 1建立独立的纯天然资源门牌号,隔绝 API 范围POST /user?action=updateLevel 2采用 HTTP 代词表述对纯天然资源的操作形式GET /users/001Level 3采用 API 超媒体(HATEOAS,回到的 body 中检索相关的纯天然资源门牌号 ){“links”:[“/users/”,”/products/”]}

依照自己的应用领域情景选择相关联的适用性数学模型,一般而言控制系统适用性数学模型在 Level 2 左右。

防止单纯PCB

API 如果服务项目销售业务潜能的PCB,防止单纯PCB让 API 全盘变成了资料库操作形式USB。比如记号订货状态为已支付,如果提供更多形如 POST /orders/1/pay 这样的API。而非 PATCH /orders/1,然后透过具体内容的表头预览订货。

因为订货支付是有具体内容的销售业务方法论,可能涉及到大量复杂的操作形式,采用单纯的预览操作形式将销售业务方法论泄漏到控制系统之外。同时控制系统外也须要知道 订货状态 这个内部采用的表头。

更重要的是,破坏了销售业务方法论的PCB,同时也会负面影响其他非功能需求。比如,权限控制、日志记录、通知等。

好的USB如果做到不多东西,不少东西。 怎么理解呢?在用户修正密码和修正个人资料的情景中,这两个操作形式看起来很类似,然后结构设计 API 的时候采用了两个通用的 /users/1/udpate URI。

然后表述了两个对象,这个对象可能直接采用了 User 这个类:

{ “username”: “用户名”, “password”: “密码” }

这个对象在修正用户名的时候, password 是不必要的,但是在修正密码的操作形式中,两个 password 表头却不够用了,可能还须要 confirmPassword。

于是这个USB变成:

{ “username”: “用户名”, “password”:”密码”, “confirmPassword”:”重复密码” }

这种类的复用会给后续维护的开发人员带来困惑,同时对消费者也非常不友好。合理的结构设计如果是两个分离的 API:

// POST /users/{userId}/password { “password”:”密码”, “confirmPassword”:”重复密码” } // PATCH /users/{userId} { “username”:”用户名”, “xxxx”:”其他可预览的表头” }

完全穷尽,彼此独立

API 间尽量遵守完全穷尽,彼此独立 (MECE) 准则,不如果提供更多相互叠加的 API。比如订货和订货项这两个纯天然资源,如果提供更多了形如 PUT /orders/1/order-items/1 这样的USB去修正订货项,USB PUT /orders/1 就不如果具备处理某两个 order-item 的潜能。

这样的好处是不会存在重复的 API,造成维护和理解上的复杂性。如何做到完全穷尽和彼此独立呢?

单纯的方法是采用两个表格结构设计 API,标出每个 URI 具备的潜能。

URI销售业务潜能/orders/1对订货本身操作形式/orders/1/order-items对订货项操作形式

为二级 URI 结构设计。聚合根间如果全盘没有任何联系,实体和聚合根间的责任如果明确。

产生这类问题的根源还是缺乏合理的抽象。如果存在 API 中可以透过用户组操作形式用户,透过用户的 URI 操作形式用户属于的用户组,这其中的问题是缺少了成员这一概念。用户组下面的本质上并不是用户,而是用户和用户组的关系,即成员。

版化

两个对外开放的服务项目,极大的概率会发生变化。销售业务变化可能修正 API 参数或响应数据结构,以及纯天然资源间的关系。一般而言,表头的增加不会负面影响旧的应用程序运行。但是当存在许多破坏力修正时,就须要采用新的版将数据导向到新的纯天然资源门牌号。

版信息的数据传输,可以透过下面几种形式

URI 前缀HeaderQuery

常见的反模式是透过增加 URI 后缀来实现的,比如 /users/1/updateV2。这样做的缺陷是版信息入侵到销售业务方法论中,对路由的统一管理带来不便。

采用 Header 和 Query 发送版信息则较为相似,不同之处在于,采用 URI 前缀在 MVC 框架中实现相对单纯,只须要表述好路由即可。采用 Header 和 Query 还须要编写额外的拦截器。

合理命名

结构设计 API 时候的命名涉及多个地方:URI、允诺参数、响应数据等。通常来说最主要,也是最难的两个是全局命名统一。

其次,命名须要注意这些:

尽可能和领域名词保持一致,比如聚合根、实体、事件等RESTful 结构设计的 URI 中采用名词复数尽可能不要过度简写,比如将 user 简写成 usr尽可能采用不须要编码的字符

用领域名词来对 API 结构设计命名不是一件特别难的事情。识别出的领域名词可以直接作为 URI 来采用。如果存在多个单词的连接可以采用中横线,比如 /orders/1/order-items

安全

安全是任何一项软件结构设计都必须要考虑的事情,对于 API 结构设计来说,暴露给内部控制系统的 API 和开放给外部控制系统的 API 略有不同。

内部控制系统,更多的是考虑是否足够健壮。对接收的数据有足够的验证,并得出错误信息,而不是什么信息都接收,然后内部销售业务方法论如果边界值的负面影响变得莫名其妙。

而对于外部控制系统的 API 则有更多的挑战。

错误的调用形式USB滥用浏览器消费 API 时因安全漏洞导致的非法访问

所以结构设计 API 时如果考虑响应的应对措施。针对错误的调用形式,API 不如果进入销售业务处理流程,及时得出错误信息;对于USB滥用的情况,须要做许多限速的方案;对于许多浏览器消费者的问题,可以在让 API 回到许多安全增强头部,比如:X-XSS-Protection、Content-Security-Policy 等。

API 结构设计评审清单

URI 命名是否透过聚合根和实体统一URI 命名是否采用名词复数和连接线URI 命名是否都是单词小写URI 是否暴露了不必要的信息,比如 /cgi-binURI 规则是否统一纯天然资源提供更多的潜能是否彼此独立URI 是否存在须要编码的字符允诺和回到的参数是否不多不少纯天然资源的 ID 参数是否透过 PATH 参数传递认证和授权信息是否暴露到 query 参数中参数是否采用奇怪的缩写参数和响应数据中的表头命名统一是否存在无意义的对象包装 比如 {“data”:{}}出错时是否破坏约定的数据结构是否采用最合适的状态码是否采用最合适的媒体类型响应数据的单复是否和数据内容一致响应头中是否有缓存信息是否进行了版管理版信息是否作为 URI 的前缀存在是否提供更多 API 服务项目期限是否提供更多了 API 回到所有 API 的检索是否进行了认证和授权是否采用 HTTPS是否检查了非法参数是否增加安全性的头部是否有限流策略是否支持 CORS响应中的时间文件格式是否采用 ISO 8601 标准是否存在越权访问

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务