您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

API开发者永不“REST”

时间:2020-11-30 13:50:58  来源:  作者:

免责声明:尽管标题有争议,但本文并不是试图证明RPC比REST更好,或者GraphQL比RPC更好。相反,本文的目的是向你介绍这些方法的大致情况以及它们的优缺点。最终的选择将会是一个权衡。

尽管 HTTP 是一个应用层(例如,L7)协议,但在 API 开发方面,HTTP 实际上扮演着一个较低层次的传输机制的角色。

在 HTTP 上如何实现 API 有许多方法,它们在概念上有所不同:

  • REST
  • RPC
  • GraphQL

...但是一个普通的开发人员需要知道的实际清单并不局限于这三个家伙。在这个领域中还有 JSON、gRPC、protobuf 等其它术语。让我们试着一次性了解所有这些术语吧!

API开发者永不“REST”

 

代表性状态转移(REST)

首先,REST只是一种软件架构风格。它是一组设计约束,而不是具体的协议。REST 依赖于资源的概念。例如,一个 REST API 是由一组资源(名词)和与这些资源交互的有限数量的动作(动词,查询 fetch、创建 create、更新 update、删除 delete 等)组成。它在思想上非常接近最初的 HTTP 设计,主要基于资源(URLs)和方法(GET、POST、PUT、DELETE)。因此,从实现的角度来看,REST 模型到 HTTP 协议的映射相对简单:

# Create new bookPOST http://myapi.com/books/ (author="R. Feynman", year=1975) -> book_id
# Get book with ID = 1GET http://myapi.com/books/1 () -> (id=1, author="R. Feynman", year=1975)
# Update book with ID = 1PUT http://myapi.com/books/1 (id=1, author="Richard Feynman", year=1975) -> (...)
# Delete book with ID = 1DELETE http://myapi.com/books/1 () -> nu

可能每一个现代 web 框架都提供了构建一个 REST 风格的 Web 服务所需的所有现成工具。从客户端的角度来看,调用一个 REST API 非常简单——它只需要将指定的 HTTP 方法发送到一组预定义的 URLs。

然而,从 API 设计者的角度来看,如何用资源术语(即名词)表示现实世界的领域并保持有限数量的动作(即动词)是并不明显的。令人惊讶的是,尽管 REST 一次在当今被广泛使用,但被认为是真正的 REST 风格的现代 API 并不多。在设计 REST 风格的 Web 服务时坚持纯粹,或导致 API 设计非常笨重。

远程过程调用(RPC)

同样,RPC也是一种 API 设计技术。RPC 聚焦于动作(动词)概念,这通常使得涉及到的资源(名词)非常原始和特别。对于业务模型中的每个过程或事务,API 设计者只需要添加一个 RPC 端点:

# Create new bookcreateBook(author, year) -> book_id
# Get book by IDgetBook(book_id) -> book
# Change book's authorsetBookAuthor(book_id, author) -> null
# Delete book by IDdeleteBook(book_id) -> nu

在幕后,应该有另外一层将这样的过程调用映射到 HTTP 请求。例如,setBookAuthor(1, "Richard Feynman")会被这样映射:

<span role="presentation" style="box-sizing: border-box; padding-right: 0.1px;">POST http://myapi.com/set-book-author/ (book_id=1, author="Richard Feynman") -> null</span role="presentation" style="box-sizing: border-box; padding-right: 0.1px;">

现在,让我们比较一下 REST 和 RPC 中改变作者姓名的任务。虽然在 RPC 中的实现看起来比较简单,但在 REST 风格的实现中有许多有争议性的问题需要回答。如果作者的名字是 book 的一个属性,那么我们是否应该在发送PUT /books/1 时,提供一个包含修改过的作者字段的完整的 book 对象?如果客户端没有完全的 book 对象怎么办?我们应该先获取 book 对象,还是只传送 book ID 和新的作者名字?但是服务端的其它属性怎么办?如果一个几乎空白的PUT 请求到达,它们是否应该归零(这将是灾难性的,但是与 REST 原则的决定一致)?或者我们应该放弃 HTTPPUT 方法,开始使用PATCH 方法(你听说过这个方法吗)?

幸运的是,如果我们遵循 RPC 方案,我们可以简单忽略上面这些问题。但是,当然也有一个缺点——一个典型的 RPC API 通常包含大量的自定义过程。显然,这使得 RPC 模型到 HTTP 层的映射是一个不平凡的任务。好在 API 设计者很少需要考虑这一部分。有很多库在 HTTP 上实现了 RPC 层,其中一些库非常杰出(是的,我说的是谷歌的 gRPC 和脸书的 Thrift)。但是 RPC 方案还有一个更复杂的问题...

一打丰富的 REST 资源结合 3-5 个 HTTP 方法通常可以覆盖一百个用例。REST API 故意为领域模型引入了一个常规结构,使其增长和演化更加可控。相反,RPC APIs 是自然增长的。引入一个新的用例通常需要在已经膨胀的列表中再增加几个 API 端点。由于 API 设计没有强制面向实体的结构,因此在相对短的时间内,RPC 调用的数量可能会超过一个团队可以处理的最大复杂度。

GraphQL

现在,,我们已经知道 RPC 和 REST 方案都不理想。REST 存在过度和欠缺查询问题,可能会导致在设计阶段的比较耗神。但是如果我们尝试用一百个特别的 RPC 端点来取代面向实体的设计,随着时间的推移,维护过度增长的 RPC API 会是一个噩梦。

GraphQL试图解决这两种技术的弱点。假设面向实体的领域模型有助于开发人员长期安心,GraphQL 方案从定义模板开始,例如资源集(即名词)和它们的关联关系。听起来很像一张图,不是吗?有了正式的模板定义,GraphQL 在其上构建了一个相当复杂的服务器和客户端。厚客户端允许查询(QL 代表 query language,即查询语言)自定义的和组合的资源。厚服务器知道如何根据客户端的查询和领域模板来填充响应。

因此,GraphQL API 基本上由一个端点组成。即,没有臃肿的 API 了。同时,它超级灵活和可以定制的查询有助于避免从服务器查询不必要的数据。此外,开发人员仍然可以从正式的面向实体的领域模板中受益。但是凡事总是有代价的。这里的代价是 GraphQL 客户端和服务器端的极度复杂性。所以,是的,一切都关乎取舍...

protobuf、JSON 等怎么样?

活动部分的适当分类能够有助于你将注意力集中在 API 开发领域。现在,我们已经知道 REST 和 RPC 仅仅只是架构风格。而 GraphQL,我倾向于认为它也是一种风格,即使从技术上来讲它是一种由运行时支持的正式语言。

但是,如果 GraphQL 是由一个特定实现支持的,那么我们可能期望 RPC 和 REST 也有相同的实现支持。事实上,确实有很多著名的 RPC 框架——gRPC、Apache ThriftApache Avro等等。令人惊讶的是,REST 框架中似乎没有明显的领导者。可能是因为 REST 在技术上非常接近 HTTP,而且几乎每个 Web 框架都已经很好地支持了它。

嗯,但是protobuf怎么样?显然,它只是数据在通过网络被发送或存储到某个地方之前对其进行序列化的方法之一。gRPC 是一个特殊的 RPC 框架,完全依赖 protobuf。而且由于这两个技术通常是一起使用的,而且被一起发布,因此很多人都将 gRPC 和 protobuf 交互使用。然而,在你的REST风格的API中使用protobuf也非常不错,protobuf 可以用作一种编码格式,我们目前在工作中对我们的一些服务就是这么做的。因此,protobuf 不应该与 REST 或 RPC 框架一起比较,而是可以与 XML 或 JSON 一起比较。

更让你困惑的是,Apache Thrift 有它自己的序列化格式,称作 Thrift!即,gRPC 使用 protobuf 编码格式,而 Thrift 使用 Thrift 编码格式

总之,设计一个 HTTP API 有许多不同的架构风格。其中最流行的三种是 REST、RPC 和 GraphQL。每一种风格都可以用很多种方法实现,而且有很多著名的框架,例如 gRPC 和 Apache Thrift。在底层,它们依赖更低级别的机制,如数据序列化(protobuf、JSON、XML)或协议(JSON-RPC、 XML-RPC)。而且较低级别的代码有时会在不同的风格之间复用,这使得整个 API 开发领域乍一看都非常复杂。

作者介绍

Ivan Velichko 是一名涉及很多领域且具有 10 年实践经验的软件工程师;热衷于可靠性和分布式系统。软件开发不仅是专业还是爱好。最有意义的活动是增加对复杂系统的理解。

原文链接

API Developers Never REST



Tags:API   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Tags: API  点击:(6)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  Tags: API  点击:(20)  评论:(0)  加入收藏
10月18号, W3C中网络平台孵化器小组(Web Platform Incubator Community Group)公布了HTML Sanitizer API的规范草案。这份草案用来解决浏览器如何解决XSS攻击问题。 网络安全中...【详细内容】
2021-12-07  Tags: API  点击:(18)  评论:(0)  加入收藏
当我们通过kubectl来查看、修改Kubernetes资源时,有没有想过后面的接口到底是怎样的?有没有办法探查这些交互数据呢?Kuberenetes客户端和服务端交互的接口,是基于http协议的。所...【详细内容】
2021-11-23  Tags: API  点击:(29)  评论:(0)  加入收藏
前言客户端请求API,通常需要通过返回码来判断API返回的结果是否符合预期,以及该如何处理返回的内容等。相信很多同学都吃过返回码定义混乱的亏,有的API用返回码是int类型,有的是...【详细内容】
2021-10-28  Tags: API  点击:(51)  评论:(0)  加入收藏
凭借着平缓的学习曲线和简单直接的语法,Python在全球范围内的受欢迎程度,正在呈指数级增长。该编码语言往往可以被用于Web开发、软件开发、数学计算、系统脚本、以及几乎所有...【详细内容】
2021-09-22  Tags: API  点击:(47)  评论:(0)  加入收藏
Guava提供的RateLimiter可以限制物理或逻辑资源的被访问速率,咋一听有点像java并发包下的Samephore,但是又不相同,RateLimiter控制的是速率,Samephore控制的是并发量。RateLimit...【详细内容】
2021-09-17  Tags: API  点击:(72)  评论:(0)  加入收藏
前言前后端分离开发模式中,api文档是最好的沟通方式。今天就来说一说如何整合Swagger生成一套漂亮、美观、实用的接口文档。 源码传送门: https://gitee.com/huoqstudy/xiliu-...【详细内容】
2021-09-08  Tags: API  点击:(65)  评论:(0)  加入收藏
注:商业级功能效果演示,非开源,无源码。研发基础在之前AJAX请求数据加密效果之上,更进一步,对返回数据加密。之前是单纯用于登录场景。更广泛的场景是所有此类AJAX WEB API接口。...【详细内容】
2021-09-03  Tags: API  点击:(73)  评论:(0)  加入收藏
最近一连串的 API 安全事件(Peloton、Experian、Clubhouse 等)无疑迫使许多安全和开发团队仔细检查他们的 API 安全状况,以确保它们不会成为下一个被攻击对象。创建面向外部受...【详细内容】
2021-09-01  Tags: API  点击:(59)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的&emsp;&emsp;程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条