将Okcupi188bet金宝搏官网d从休息移动到GraphQL

已经有很多关于从REST API转移到GraphQL API¹的好处的文章。但假设你已经被说服了。如果你想要转换一个拥有数百万用户的网站,确保性能不会受到影响真的不想把它搞砸:你该怎么做?
我们去年开始了这段旅程,并活着出来讲述了这个故事!我们的GraphQL API现在是OkCupid的官方API,所有客户端都采用它:我们188bet金宝搏官网的iOS和Android应用,以及我们的桌面和移动网页单页React应用。188博金宝电子体育频道
所以,这是我们如何解决这个巨大的项目。我将谈谈我们所构建的内容,我们所提出的测试新代码的策略,以及在技术方面可以做得更好的一些事情。免责声明:本文更多地是关于过程而不是代码本身;要了解我们必须克服的性能问题以达到与之前API相同的水平,请阅读我们的第一个版本在这里.
但首先,我们来看一些数据
我们的GraphQL API已在生产中为1年半,我们已停止向我们的REST API添加新功能。该图处理每分钟高达170K的请求,它由227个实体组成。
我们还没有完全弃用REST API,但是从请求量(我们已经添加了支持最流行页面的实体)来看,我们已经完成了一半以上的客户端转换,从实体数量来看,可能还不到一半。
我们是如何做到的
由于这是我们(节点,Apollo Server,Docker²)的全新技术堆栈和存储库,因此我们需要弄清楚在不扰乱生产的情况下验证其效率的计划。我们的进程是:
- 选择要转换的适当页面
- 构建架构
- 添加一个影子请求来调用新的API,同时仍然通过REST API获取数据
- 使用更改数据源的真实用户进行A / B测试
我们在2019年1月初开始项目,1月28日发布shadow查询,3月13日开始A/B测试,4月30日全面发布。所以,只需4个“简单”步骤,你也可以在“仅”4个月的时间内制作出一张图表!
让我们深入研究每一步。
1.选择要转换的适当页面
我们决定把OkCupid的对话页面作为我们的试188bet金宝搏官网验台。在这个页面上,用户可以看到他们正在进行的对话列表,以及“相互匹配”(可以开始新对话的人)列表:

选择一个能让你模拟网站核心部分的页面是很重要的;这将帮助您确定约定,充实数据模型的重要部分,为未来的工作创建一个更好的基础,并只是一个更好的概念验证。页面越“真实”,就越能帮助您了解新API是否能够工作。
我们选择了Conversations页面,这让我们考虑如何表示:
用户
:用户帐号的基本信息匹配
:关于两个用户如何相互关联的有状态信息(例如,匹配百分比,是否喜欢另一个,等等)谈话
:基本对话信息(如发送方、最后一条消息的片段、发送时间)
这也让我们想到了一些可重用的API概念,比如分页。
2.建立你的模式
对于许多第一次进行模式设计的团队来说,这可能是一个具有挑战性的步骤——对我来说就是这样!一些建议:
- 做研究。有很多很棒的关于图式的文章GraphQL文档中的基本示例, 到GitHub和Yelp的公共api继电器的文档.在这里的阿波罗团队大声喊叫;我们在这个阶段得到了很大的帮助。
- 不要担心REST API如何格式化它的数据。最好将模式设计得更具有表达性和习惯用法,而不是受以前API返回的内容的限制。
- 是一致的。我们之前的API主要是
snake_case
,但有几个丑陋的词语(例如,用户标识
和displayname
).这是你让你的域名更标准和可读的机会,所以抓住它! - 要具体。在图中对字段的命名越准确,在需要进行重大更改时就越容易迁移到新字段。例如,
User.essaysWithDefaults
比User.essays
. - 将你的研究成果应用到你的团队中。例如,在研究分页标准时,我很想使用Relay的规范,但发现它依赖于像这样的术语
边缘
年代和节点
这比我们想在图表中向客户展示的更加临床(我们决定返回一个列表数据
³)。
3.添加阴影请求
在具有GraphQL向真正的用户提供数据之前,我们在使用Shadow请求中测试了我们的系统:在我们的目标页面上,用户从REST API请求其数据,然后在显示REST数据后与GraphQL相同(丢弃欺骗数据)。这让我们比较了两个API的性能并在用户找到它们之前解决问题。
我们当然不是第一个想到这一点的人,但这对我们来说是一个非常重要的一步。我们这一API的初步草案几乎两倍的时间REST API,这显然不酷。发布一个影子请求可以让我们在不影响实际用户体验的情况下对这些性能问题进行分类。
关于哪里出了问题以及我们如何使GraphQL达到速度平价的技术方面,请参阅有关的文章第一个GraphQL部署.
4.运行实验
最后一步是用实际用户测试新API和旧API !因为我们已经验证了响应时间与影子请求相似,所以我们有信心发布A/B测试。
你期望的实验不看到变化是很棘手的,因为你试图证明什么都没发生。所以在这样的实验中,你追踪的数据本质上是没有意义的,除非出了什么问题。
所以你不应该寻找统计数据的显著变化,而应该为你的实验设置一个持续时间;一旦你达到了这个期限,但仍然没有看到显著的变化,你就可以满怀信心地发行游戏了。对于我们来说,这是一个月的运行时间(每个组的用户超过10万)。和……这工作!
还有什么可以做得更好
没有第一稿是完美的(第二稿也是如此,至少对我来说)。虽然发布API的过程进展顺利,但在发布后我们学到了一些技术方面的东西。
错误处理
我们没有任何关于如何从GraphQL突变中返回错误的结构,当我们意识到有问题时,我们有各种各样的方法向客户显示错误。一个看起来很有趣的解决方案是标准化错误
我们可以在特定变异载荷下扩展的类型。这篇媒体文章有一个非常深入的报道好的错误风格.
业务逻辑应该何去何从?
当遇到涉及业务规则的产品特性时,将该逻辑添加到API层是很有诱惑力的,特别是如果您需要依赖另一个团队来实现它的话。
例如,我们构建了一个功能,可以显示一个喜欢你并给你发消息的所有人的列表。我们将整个列表呈现给付费用户,但对于免费用户,我们只呈现第一个列表,然后是一系列占位符。这个特性的第一个版本有检查用户付费状态的逻辑,并在API层用占位符替换卡片。
在使用图一段时间之后,我们意识到业务逻辑在后端集中时工作得最好,我们的图的角色是以一种对客户有意义的方式获取、格式化和呈现后端数据。
就这样,你们
总的来说,我们的过程非常顺利;它允许我们将一些内容快速投入生产,以验证我们的技术决策,在错误到达用户面前进行修复,并根据之前的API测试我们的更改。
如果您决定进行类似的旅程,我们希望本路线图对您有所帮助。好运!
谢谢凯瑟琳·埃里克森,雷蒙德孙和OkCupid网络188bet金宝搏官网团队阅读本文草稿。
1.对我们来说,它归结为:更富有表现力的方式为客户与我们的数据交互,更有效检索数据的方式用更少的网络请求,更大的灵活性,为我们的客户创造新功能没有API变化一旦图建立了一点,和一个技术迅速被采用作为一个社区的标准API。
2.这是一个新项目,构建在一个新的存储库中,并与我们的后端和客户端代码库分开部署。它使用Apollo Server和Express在Node中运行。我们的数据是通过调用最初版本的REST API来提供的,但后来我们转而使用gRPC直接调用后端。
API是与Docker一起部署的:我们用CI构建Docker映像,并通过Docker Swarm将这些映像编排到我们的web服务器上。非常感谢我们的行动团队Hugh Tipping,他将Docker Swarm和启动脚本整合在一起,并提供了大量的Docker经验和支持!情感支持。
我们在所有平台(桌面/移动网络,iOS和Android)上使用Apollo Client,并与Apollo Studio集成,使用他们的Oper188博金宝电子体育频道ation Registry以确保安全,并跟踪速度和现场使用情况。
3.边缘
年代和节点
我们觉得不对,但Relay对分页光标的描述非常准确。因此,我们为项目使用数据数组,并以relay为灵感PageInfo.
实体:
描述一页分页数据时使用的通用格式。"""
类型PageInfo {
关键是要得到前一页的结果,如果可用的话。"""
:字符串
关键是获得下一页的结果,如果可以的话。"""
后:字符串
一个布尔值,表示有更多的结果可用。"""
hasMore:布尔!
可用结果的总数。"""
总:Int !
}
"""确保分页结果包含当前页面信息的界面。"""
接口PageResult {
pageInfo: pageInfo !
}
用户对话的分页列表。"""
typeconversationconnection实现PageResult {
数据:【讨论】!
pageInfo: pageInfo !
}
扩展类型User {
""" "该用户的对话列表。"""
谈话(
limit: Int = 20
:字符串
后:字符串
): ConversationConnection !
}
最初发表在https://tech.188bet金宝搏官网okcupid.com2020年11月13日。