HappyNewYear
随着科技知识和产品广泛普及和应用,人们越来越深刻认识到及早地对儿童STEM启蒙教育的重要性。把教育孩子的责任都交给或推卸给学校的观念也应该改变,同时也应改变把家庭教育仅仅看成吃穿照看和识字识数的传统观念。通常的教育就是指上学,但当前的教育内容和教育方式已经发生了巨大变化,家长必须对此有所认识。广义的教育实施单位分为家庭、学校和社会三个单位,他们在人生的不同阶段起着不同的作用,教授不同的内容,采用不同的教育方式,尤其是对小学生,家庭担负非同寻常的教育作用。我们在制定任何一项教育内容的时候就不应忽视家庭的作用,比如传统上都采取留作业的方式,把学校教育的内容强加到家庭教育中去。但是这种处于被动的家庭教育方式且不说对于以书本和书写为内容的传统教育真的是否合适,对于STEM内容的教育肯定是不合适的。现在网络教育的出现为家庭教育提供了有利的条件和可能。
现在有关STEM教育的网站很多,但把家庭STEM教育作为专题的并不多。我们在这里介绍一个专门以家庭STEM为题的网站,即Steamsational网,以下简称STEAM网。
STEAM网站是一个经过多年建设和精心设计的庞大的网站,内容非常丰富。它把STEM教学分为课堂STEM课程(ClassSTEMPrograms)和家庭STEM课程(HomeSTEMprograms)两部分,但主要内容是家庭STEM教育。这是STEM教育中值得探索的一种方式,也是未来教育模式的一项新的探索。
Steam网隶属于雅林科学俱乐部(JarringScienceClub),创始人BrendaPriddy,从事十多年STEM教育,六年前创建了Steamsational网站。雅林科学俱乐部名下还有另外一个网站,Jarringscience.
MICHAELP.GERACI 译者
王者 策划
万佳
关于从RESTAPI迁移到GraphQLAPI的好处,已经有很多人写过这方面的文章。假设你已经接受了这个事实,那么如果你想要转换一个拥有数百万用户的网站,确保性能不受影响,并且真的不想把它搞砸,你该怎么做?
我们从去年开始了这个旅程,并获得成功,现在我们就回过头来讲这个事。我们的GraphQLAPI现在是OkCupid的官方API,被所有的客户端调用,包括我们的iOS和AndroidApp,以及我们的桌面和移动Web单页React应用程序。
这篇文章将讲述我们是如何处理这个巨大的项目的。我将介绍我们所构建的东西、我们为测试即将发布的新代码而制定的策略,以及一些在技术方面本可以做得更好的地方。
注:本文更多地是关于过程而不是代码本身,我们将在另一篇文章中讨论与性能有关的问题。
1收益我们的GraphQLAPI已经在生产环境中运行了一年半。在一年多前,我们就停止向RESTAPI添加新特性了。GraphQLAPI由个实体组成,每分钟处理17万个请求。
我们还没有完全弃用RESTAPI,从请求量方面来看,客户端的迁移工作进行了一半多,但从实体数量来看,可能还不到一半。
2我们是怎么做的对我们来说,这些是一个全新的技术栈和代码库(Node、ApolloServer、Docker),所以我们需要制定一个计划,在不中断生产环境的情况下验证其有效性。我们的流程是:
选择一个适当的页面进行转换;
构建schema;
添加影子请求来调用新的API,同时仍然通过RESTAPI获取数据;
使用真实用户进行A/B测试。
我们在年1月开始这个项目,在1月28日发布影子查询,在3月13日开始A/B测试,并在4月30日发布完整版。所以,经过4个“简单”的步骤,你也可以在4个月内得到一个在生产环境中运行的GraphQLAPI。
接下来,让我们深入探究每一个步骤。
选择一个适当的页面进行转换我们决定将OkCupid对话页面作为切入点。在这个页面中,用户可以看到自己正在进行的对话,也可以看到“匹配”列表(可以开始新对话的人):
转换之前的对话页面
选择一个网站核心页面是很重要的,这样可以帮你确定好约定条件,充实数据模型的重要部分,为未来的工作打好基础,并更好地进行概念验证。页面越“真实”,就越能帮你了解新API是否可行。
我们选择了对话页面,需要考虑如何呈现它:
User:用户基本信息;
Match:两个用户相互关联的状态信息(例如,匹配百分比,一个用户是否喜欢另一个用户,等等);
Conversation:基本的对话信息(例如,发送者、最后一条消息的片段、发送时间,等等)。
我们还要考虑到一些可重用的API概念,比如分页。
构建schema对很多第一次进行schema设计的团队来说,这可能是一个具有挑战性的步骤——对我来说就是如此!这里有一些建议:
调研。与schema有关的文章有很多,例如GraphQL文档提供的基本示例、GitHub和Yelp的公共API、Relay的文档等等。在这里要感谢Apollo团队,他们为我们提供了大量帮助。
不要担心RESTAPI的数据格式问题,最好将schema设计得更具表达性和惯用性,不要受旧API的限制。
保持一致。我们的旧API主要使用了蛇形命名格式,但也存在一些难看的组合词(例如userid和displayname)。这时候刚好是纠正这些字段名称的好机会!
具体化。GraphQLAPI中的字段名称越具体,在进行重大更改时,就越容易迁移成新字段。例如,User.essaysWithDefaults比User.essays更好。
基于调研结果为团队做一些有用的东西。例如,在研究分页标准时,我本来想用Relay的规范,但发现它对edge和node等术语太过依赖,对于客户端来说不够友好(我们最终决定返回一个data列表)。
加入影子请求在GraphQL为真实用户提供数据前,我们在生产环境中使用影子请求对系统进行测试:在我们的目标页面上,用户向RESTAPI请求数据,在显示REST数据之后,再向GraphQLAPI发出相同的请求。这样我们就可以比较两个API的性能,并在用户发现问题前修复它们。
我们当然不是第一批想到这么做的人,但这对我们来说是非常重要的一步。
我们在这个API的第一个草案上花费的时间几乎是RESTAPI的两倍,这显然不是很酷。使用影子请求让我们可以在不影响实际用户体验的情况下诊断性能问题。
进行实验最后一步是使用真实用户来测试新的API。因为已经验证了响应时间与影子请求是差不多的,所以我们有信心进行A/B测试。
如果你期望在实验中看不到变化,那么这种实验是没有意义的,因为你试图证明什么都没有发生。在这样的实验中,你关心的统计数据在本质上是没有意义的,除非发生了什么问题。
因此,你应该为实验设置一个持续时间,而不是观察统计数据是否发生了显著变化。一旦达到了设定的持续时间,并且仍然没有看到显著的变化,就可以对系统满怀信心了。
在我们的案例中,这个持续时间是一个月(每组实验超过了10万用户)。
3哪些地方可以做得更好?初稿总是不完美的(即使是第二稿也是,至少对我来说)。虽然发布API的过程进行得很顺利,但在发布之后我们还是学到了一些技术上的东西。
错误处理我们没有针对GraphQL更新API返回的错误定义好结构。当我们意识到这个问题时,已经向客户端显示了各种各样的错误。一个看起来比较好的解决方案是标准化一个Error类型,我们可以在给定的消息体中对其进行扩展。这篇文章非常深入地讲解了如何设计错误类型。