简体中文
  • RESTful
  • REST
  • RPC
  • API
  • architecture
  • API design

只用 POST?让我们结束这场荒谬的 API 设计争论

揭穿“只用 POST”的 API 神话,解释为什么它源于对 API 设计原则的误解,并阐明 RESTful 和 RPC 架构风格的适用场景。

Yijun
Yijun
Developer

最近,关于是否使用“只用 POST”设计 API 的讨论引起了我的注意。在深入研究这场争论后,我发现不仅争论的问题毫无意义,它还暴露了许多开发者对 API 设计本质的误解。今天,让我们深入探索 API 设计的核心理念,看看为什么这场争论本不该存在。

“只用 POST” 的误解

那些提倡用“只用 POST”取代 RESTful API 规范的开发者显然没有抓住 API 设计中最重要的要点。他们的论点通常包括:

  1. 简化设计:一个方法可以处理所有事情
  2. 安全性:POST 参数不会出现在 URL 中
  3. 灵活性:POST 可以发送任何数据结构

乍一看,这些论点似乎有点道理。但实际上,这种观点混淆了 HTTP 方法的选择和 API 设计风格,二者是不同层次的问题。POST 仅仅是 HTTP 协议中的一种方法,而 REST 是一种 API 设计风格。

API 设计的本质

在讨论特定的 API 风格之前,我们需要理解 API 设计的核心目的是什么。一个好的 API 应该是:

  1. 清晰易懂:其他开发者(包括未来的你自己)应该能够直观地理解每个端点的用途
  2. 一致性:遵循某种规范以降低学习成本
  3. 可扩展性:能够轻松进行版本控制和功能扩展
  4. 高效性:考虑性能和资源利用的效率

RESTful API:不仅仅是 HTTP 方法的选择

RESTful API 只是众多 API 设计风格中的一种,专注于资源及对资源的操作。让我们以一个简单的博客系统为例,看看 RESTful API 的设计是如何进行的:

  1. 获取所有文章:

  2. 获取特定文章:

  3. 创建新文章:

  4. 更新文章:

  5. 删除文章:

在这个例子中,我们可以看到:

  • API 设计围绕“文章”资源展开
  • 不同的 HTTP 方法用于表示不同的操作
  • URL 结构清晰,指明所操作的资源

这种设计方法使得 API 更加直观,且易于自解释,使开发者能够轻松理解每个端点的功能。

RPC:理解“只用 POST”背后的 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 风格的例子中,我们可以看到:

  1. 服务定义清楚地列出了所有可用操作(在这个简化的例子中是 GetArticleCreateArticle)。
  2. 每个操作都有明确的请求和响应类型。
  3. 客户端代码看起来像是在调用一个本地的异步函数,使用 await 来等待结果,从而进一步隐藏了网络通信的复杂性。
  4. 不需要手动构建 HTTP 请求或解析 JSON 响应。

尽管底层可能仍使用 HTTP/2 作为传输协议,RPC 框架(如 gRPC)为开发者提供了一个抽象层,使远程调用看起来和感觉上都像本地函数调用。

因此,我们可以看到,大多数关于“只用 POST”和 RESTful API 的争论,实际上应该是关于这两种 API 风格:REST 和 RPC 的讨论。然而,关键是要认识到这两种风格各有其适用场景,选择应该基于项目的具体需求,而非个人喜好。

REST vs RPC:没有绝对的优劣

既然我们了解了 REST 和 RPC 之间的区别,让我们来看一下它们各自的适用场景:

  1. REST 适用于:
    • 面向资源的应用程序(如内容管理系统、博客平台、电商网站)
    • 需要良好缓存支持的场景(GET 请求天然可以被缓存)
    • 希望利用 HTTP 语义的项目(如使用合适的状态码)
    • 面向公众的 API,要求良好的可发现性和自描述性
  2. RPC 适用于:
    • 面向操作的应用程序(如复杂的数据处理操作、工作流控制)
    • 需要高性能和低延迟的系统(如实时交易系统)
    • 内部微服务之间的通信(可能需要更灵活的参数传递)
    • 操作不能简单映射为 CRUD(创建、读取、更新、删除)操作时

风格的选择应根据具体需求来决定。在某些情况下,你甚至可能在同一个系统中混合使用这两种风格,以满足不同部分的需求。

结论

  1. API 设计的核心在于清晰性、一致性、可扩展性和高效性,而不是局限于某种特定的方法或风格。
  2. RESTful 和 RPC 都是成熟的 API 设计范式。选择它们应基于项目需求,而非个人偏好。
  3. 如果你决定使用“只用 POST”,那么请按照 RPC 风格设计你的 API。和 RESTful 一样,它在业界也是一种常见的 API 规范,但应在合适的场景中使用。
  4. 不要被表面的技术细节所迷惑。真正重要的是你的 API 是否能有效服务于用户和业务需求。
  5. 在设计 API 时,多花些时间思考你的资源模型、业务逻辑和用户需求,而不是在纠结该使用哪个 HTTP 方法。

让我们把注意力从这些无意义的争论中转移开,专注于设计真正优秀的 API。毕竟,技术是用来解决问题的,而不是制造问题的。