单一端点而不是 API - 有啥缺点?

Posted

技术标签:

【中文标题】单一端点而不是 API - 有啥缺点?【英文标题】:Single endpoint instead of API - what are the disadvantages?单一端点而不是 API - 有什么缺点? 【发布时间】:2021-04-19 04:50:58 【问题描述】:

我有一个通过 HTTP 公开的服务。大多数流量输入通过单个 HTTP GET 端点进入,其中有效负载被序​​列化和加密 (RSA)。客户端系统有通用代码,保证序列化和反序列化成功。编码参数之一是操作类型,在我的服务中有一个巨大的switch(几乎 100 个cases),用于检查执行了哪个操作并执行正确的代码。

        case OPERATION_1: 
            operation = new Operation1Class(basicRequestData, serviceInjected);
            break;
        
        case OPERATION_2: 
            operation = new Operation2Class(basicRequestData, anotherServiceInjected);
            break;
        

端点有几种类型,其中一些是典型的资源端点(GET_something、UPDATE_something),其中一些是基于方法的(VALIDATE_something、CHECK_something)。

我正在考虑重构服务的 API,使其更加 RESTful,尤其是在系统的基于资源的部分。为此,我可能会将端点拆分为适当的端点(例如 /resource/id/subresource)或类似 RPC 的端点(/validateSomething)。我觉得这样会更好,但是我无法为此提出任何论据。

问题是:重构解决方案的优点是什么,接下来:当前解决方案的缺点是什么?

当前的解决方案将客户端与服务器分开,它具有可扩展性(添加新端点需要在公共代码中添加新的操作类型)并且非常清楚,两个客户端以两种不同的编程语言使用它。我知道该 API 在 Richardson 的模型中被标记为 0 成熟度,但是我无法解释为什么我应该将其更改为 3 级(或至少 2 级 - 资源和方法)。

【问题讨论】:

【参考方案1】:

大部分流量输入通过单个 HTTP GET 端点进入,其中有效负载被序​​列化和加密 (RSA)

这可能是一个问题,因为 HTTP 规范非常清楚带有有效负载的 GET 请求是out of bounds。

GET 请求消息中的有效负载没有定义的语义;在 GET 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。

可能值得花一些时间来回顾一下,因为您现有的实现似乎有效,那么问题是什么?

这里的问题是互操作——其他人控制的进程能否与您控制的进程成功通信? HTTP 标准为我们的“自我描述消息”提供了共享语义;当您违反该标准时,您将失去与您无法直接控制的事物的互操作性。

这反过来又意味着您不能随意利用我们已经拥有的支持 HTTP 的广泛解决方案,因为您在您的案例中引入了这种不一致。

适合您当前正在做什么的 HTTP 方法? POST


REST(又名 Richardson Level 3)是万维网的架构风格。

您的“一切都是对单一资源的信息”的方法放弃了许多使万维网取得灾难性成功的优势。

其中最明显的是caching。 “Web 规模”之所以成为可能,部分原因是标准化的缓存支持大大减少了我们需要进行的往返次数。然而,HTTP 中的缓存颗粒是资源——所有内容都来自请求的目标 uri。因此,通过单个目标 uri 共享所有信息,您将失去细粒度缓存控制。

您还失去了安全的请求语义 - 由于每条消息都隐藏在一个方法类型中,通用组件无法区分“有效只读”消息和请求源服务器修改其自身资源的消息。这反过来意味着您将失去预取,以及在网络不稳定时自动重试安全请求。

总而言之,您使用了一个相当聪明的application protocol 并削弱了它,给自己留下了一个传输协议。

根据您的情况,这不一定是错误的选择 - 毕竟,SOAP 是一种东西,而且您的服务似乎确实按原样工作?这意味着您目前不需要已放弃的功能。

这会让我有点怀疑,如果你不需要这些东西,为什么要使用 HTTP 而不是一些消息传递协议?

【讨论】:

以上是关于单一端点而不是 API - 有啥缺点?的主要内容,如果未能解决你的问题,请参考以下文章

只使用 Redis 而不是 RDBMS 有啥缺点?

使用服务而不是组件有啥优点和缺点?

如果我使用 Array 而不是 Vector,有啥缺点吗?

Java 泛型啥时候需要 <?扩展 T> 而不是 <T> 并且切换有啥缺点吗?

对单列使用 UICollectionView 有啥缺点?

使用带有 useReducer() 钩子的 React Context API 有啥优点和缺点?