只用 POST?让我们结束这场荒谬的 API 设计争论
揭穿“只用 POST”的 API 神话,解释为什么它源于对 API 设计原则的误解,并阐明 RESTful 和 RPC 架构风格的适用场景。
揭穿“只用 POST”的 API 神话,解释为什么它源于对 API 设计原则的误解,并阐明 RESTful 和 RPC 架构风格的适用场景。
最近,关于是否使用“只用 POST”设计 API 的讨论引起了我的注意。在深入研究这场争论后,我发现不仅争论的问题毫无意义,它还暴露了许多开发者对 API 设计本质的误解。今天,让我们深入探索 API 设计的核心理念,看看为什么这场争论本不该存在。
那些提倡用“只用 POST”取代 RESTful API 规范的开发者显然没有抓住 API 设计中最重要的要点。他们的论点通常包括:
乍一看,这些论点似乎有点道理。但实际上,这种观点混淆了 HTTP 方法的选择和 API 设计风格,二者是不同层次的问题。POST 仅仅是 HTTP 协议中的一种方法,而 REST 是一种 API 设计风格。
在讨论特定的 API 风格之前,我们需要理解 API 设计的核心目的是什么。一个好的 API 应该是:
RESTful API 只是众多 API 设计风格中的一种,专注于资源及对资源的操作。让我们以一个简单的博客系统为例,看看 RESTful API 的设计是如何进行的:
获取所有文章:
获取特定文章:
创建新文章:
更新文章:
删除文章:
在这个例子中,我们可以看到:
这种设计方法使得 API 更加直观,且易于自解释,使开发者能够轻松理解每个端点的功能。
RPC(远程过程调用)风格的 API 设计的目标是使远程服务调用看起来像是本地函数调用一样简单。
有趣的是,那些提倡“只用 POST”的人可能没有意识到他们实际上是在描述 RPC 风格。
与 RESTful API 相比,RPC 更关注的是操作本身而不是资源。这就是为什么 RPC 风格的 API 通常使用“动词 + 名词”形式,比如 getProduct(productId) 或 createUser(userData)。
在许多 RPC 实现中,所有操作通常通过 POST 请求发送到同一个端点,在请求体中指定具体的操作和参数。因此,“只用 POST”的观点实际上更接近 RPC 而不是 REST。
例如,一个基于 HTTP 的 RPC 风格“获取产品”请求可能是这样的:
现代 RPC 框架,如 gRPC,提供了更强大且更高效的实现。让我们以此为例来展示 RPC 风格:
首先,我们定义服务和消息格式(使用 Protocol Buffers):
然后,在 Node.js 客户端中使用这个服务就像调用一个本地函数一样简单:
在这个 RPC 风格的例子中,我们可以看到:
GetArticle 和 CreateArticle)。await 来等待结果,从而进一步隐藏了网络通信的复杂性。尽管底层可能仍使用 HTTP/2 作为传输协议,RPC 框架(如 gRPC)为开发者提供了一个抽象层,使远程调用看起来和感觉上都像本地函数调用。
因此,我们可以看到,大多数关于“只用 POST”和 RESTful API 的争论,实际上应该是关于这两种 API 风格:REST 和 RPC 的讨论。然而,关键是要认识到这两种风格各有其适用场景,选择应该基于项目的具体需求,而非个人喜好。
既然我们了解了 REST 和 RPC 之间的区别,让我们来看一下它们各自的适用场景:
风格的选择应根据具体需求来决定。在某些情况下,你甚至可能在同一个系统中混合使用这两种风格,以满足不同部分的需求。
让我们把注意力从这些无意义的争论中转移开,专注于设计真正优秀的 API。毕竟,技术是用来解决问题的,而不是制造问题的。