在 我称赞谷歌无情地对现代化的诱惑说“不”。 谷歌日历的秘密工程师武器:限制 谢谢你读过《无人机》!免费订阅接收新帖子并支持我的工作。 签名 "Use a frontend framework." No. JavaScript. "Use Typescript." No. Javascript. "Use a trendy CSS tool." No. CSS classnames. "Give us a native desktop app." No. Browser. "Give us dark mode." No. "Make it really fast." No. 他们对简单的承诺有助于GCal捍卫其作为数十亿普通人的默认日历的地位。 然而,对于API客户来说,相同的简单性使生活变得悲惨复杂。 这种复杂性是如何出现的,我们作为建设者可以从中学到什么。 问题:保持数据在同步 您正在构建一个名为 Cool Calendar 的酷新日历。 为了帮助用户开始,您允许他们导入现有的 Google 日历。 这将需要访问用户的Google日历数据。 你看看GCal API,看看典型的嫌疑人: “酷,”你想,“我只需要得到 ,然后获取该日历的所有事件. 当我需要更新一个事件时,我会使用 来自GET 响应”。 calendarId eventId events 你可以用几个简单的功能来完成这一切: 所有事件都在您的DB中,并且在用户从用户界面更新事件后,它们也会出现在用户的GCal中。 您打开GCal应用程序,创建一个名为“庆祝在丹尼的”的新活动,并期待您的香卷面包。 Cool Cal 应用程序已打开,但新事件没有出现。 你的空腹沉没,因为你意识到你只实施了一半的解决方案(CoolCal → GCal)。 您仍然需要确保 GCal 更改传播到 Cool 日历(GCal → CoolCal)。 否认 你知道其他人以前遇到过这种用例,所以你重新访问了GCal API文件。 幸运的是,你找到了一个叫做“指南”的指南。 」 有效地同步资源 指南很短,使你轻松。 看起来你只需要添加一些更多的电话。 因为你不知道有多少事件被更新,或者他们是什么时候,你知道你需要一个循环来收集所有事件。 有意义的。 幸运的是,这些文档包含了Java中的完整片段。 它甚至使用了 循环策略,让你感觉聪明。 do-while 当然,你可以把它转换成JavaScript,然后继续。 愤怒 一小时过去了,你已经成功地将片段转换为名为JavaScript的函数。 更新你的火焰 syncGcal() 它起作用! 每次你跑 ,用户的新 GCal 数据被添加到 CoolCal。 syncGcal() 你决定为你的麻烦添加纽约风格的奶酪蛋糕。 当你出门时,你疲惫的大脑中出现了几个问题。 syncToken在任何地方都没有坚持 syncGcal() 只有在手动调用时才起作用 How often should I run syncGcal() ? 每個小時? 每分钟? Where will I store the token? 地方存储? 该 收藏? user 新的收藏? What happens if the token becomes invalid? 我可以继续修复吗? 我需要做一个完整的导入作为备份? 什么是配额限制? 如果用户在这个过程中做出更改呢? 你变得愤怒 - 在指南没有警告你这些边缘案件,然后在你的天真假设它应该。 谈判 “我并不孤单,我可以寻求帮助,”你对自己说,就像你在治疗中练习一样。 您相信 API 文档将具有称为 你所忽略的 syncResources() 或者它会作为服务提供吗?就像某个YC公司一样,它会为您神奇地同步所有数据。 至少,会有一位理查德·斯托尔曼的弟子,他有一个MIT复制品,你可以指向克劳德。 > clone the two-way sync stuff from github.com/stallman-cal. no bugs. 抑郁症 官方文件是空的。 所有YC公司都是建设代理商。 Stallman 不信任您的盈利日历应用程序。 (有一個名為MIT的項目 ,但它只有200颗星星,不能信任。 Compass 日程表 没有人关心你的双向同步功能。 事实上,你都是孤单的。 一个眼泪落在你的机械键盘上,当你意识到你今天不会去丹尼的。 接受 经过自制的法国乾杯和午后散步后,你与你的命运相处,像一个真正的工程师,并自己做。 几周后,它终于完成了。 但你仍然不能停止想象 “为什么GCal这样做?” “这一定是这么复杂的吗?” 要求 你把自己置于谷歌的鞋子中,以反向工程的形式实现要求。 (即PRD) 产品要求 Doc 解决方案 这很有趣,所以你将解决方案作为一个解决方案来满足这些要求。 (一)TDD 技术设计 Doc 分析 最后,你觉得有资格说GCal的“给他们一个代币”解决方案是否是好的。 Token Pagination 的优势 他们可以隐藏客户端的复杂性,所以他们不需要了解一切(例如,多区域复制) Opaque tokens protect the client from overwhelm. 通过控制代币到期时间,GCal可以确保客户在增速同步过程中始终看到删除。 Cleanly handles deletions. Google 可以完全改变其存储后端、分解策略或拓扑,而不会影响客户端,这无疑使 2010 年代从 NoSQL (Megastore) 迁移到 NewSQL (Spanner) 更容易。 )。 Easier implementation changes. 超级高潮.com 弱点 Webhook告诉你一些变化,但不是什么。这意味着每个推送通知会触发一个新的增量同步调用。当电源用户频繁调整时,这会变得有趣。 Push is disconnected from sync. 增量同步是与 和 参数. 你必须选择一种或另一种方法. 这对人类来说是一个麻烦,他们在时间方面比在代币中更容易思考。 Some filters are incompatible timeMin timeMax 页面代币是短暂的。如果客户端在中间页面(7页后)出现故障,他们必须重新启动整个同步。对于大型日历,这是痛苦的。 No partial sync recovery. 替代品(以及为什么不使用它们) 底线 sync token + cursor pagination 方法是 它是Microsoft Graph(delta代币),Stripe(页面标记器)和大多数企业API使用的相同模式。 pragmatic, battle-tested pattern 谷歌选择了它,因为它允许他们隐藏内部复杂性,同时为99%的日历使用案例提供“足够好的”同步语义。 这些替代方案(事件采购,CRDT,OT)只有在GCal需要实时协作或真正的离线第一P2P同步的情况下才有意义。 完整图片 如果谷歌与GCal的目标是产生收入,他们会提供更多的文档,视频和网络研讨会。 npm i gcal 但谷歌与GCal的目标不那么雄心勃勃: >> Don’t annoy regular users so much that they download Apple Calendar. 从一个免费的API中期望这么多是不公平的。 令人惊讶的是,你可以首先与GCal集成 GCal 尊重其作为应用程序的基本组成部分的责任,将可靠性优先于采用便利性: 很多失败都不会发生。 API 会按照其文件所说的做,即使它们不会说太多。 他们不会用破坏性的变化让你感到惊讶 依然, 当他们第一次想到,“我知道,我只会与GCal集成。 there is a gap between the developer’s expectations and reality 目前,开发者必须用时间、努力和失去无辜来弥补这一差距。 但谷歌可以通过提供更多资源来减轻痛苦。 例如,文件可以提供更多的实施指南。 代码样本可以从 bare repos 演变为演示应用程序。 在平衡上,保持API简单是正确的举动。 原始的 API 可能会使电力用户感到烦恼。 但如果它不影响用户体验、收入、保留或品牌,那么保持简单。 Takeaways 为建设者 创建公共同步 API 时 Keep it boring: use existing standards 在这里,我们已经看到了GCal的API是如何建立在方针页面和同步代币上,它的事件模型也围绕着已建立的标准构建:CalDAV,iCalendar和RRULEs。 相反,他们发明了优化版本,但坚持了基本原则,这就是为什么自他们的API在2006年(与Yahoo不同)以来,有这么多成功的GCal集成的原因。 Use cursor pagination when the data is a moving target 当您阅读时发生写作时,您需要在页面上保持一致性,以避免重复和错过行。 示例:日历,电源,审计日志,仅附件流。 Use offset pagination when the data is stable 如果数据是静态的,没有同时写的,你可以用一个更简单的方法去除。 示例: 页面号码的搜索结果,小数据的管理表。 Don’t oversell the API 你知道如何在早上兴奋地完成一个PR,然后去散步......只是意识到它比你想象的更复杂,直到第二天下午才看到白天。 谷歌的API并不承诺为你做一切。 最终产品将出售API:花费你的时间让你的用户喜欢你的产品,然后担心让那些与它集成的开发人员感到高兴。 Don’t break things 如果你的整合对别人的产品至关重要,那就慢点吧。 花更多的时间测试迁移。 在启动它们之前获取有关文件的反馈。 发送“头顶”电子邮件和终端消息,以便没有人感到惊讶。 这需要一个身份的转变,从“破坏东西的头情绪编码器”到“有纪律的软件工程师”。 你不会总是得到正确的,但要认真对待责任。 一个破坏性的改变会造成比三个功能更大的伤害。 GCal的API是稳定的,所以我的睡眠成绩幸运的是,自从使用它以来一直没有下降。 当集成公共同步 API 时 Don’t start with an integration “但我的用户不会使用我的应用程序,除非它与他们已经使用的工具集成。 “但我的用户不会使用我的应用程序,除非它与他们已经使用的工具集成。 也许,但让他们告诉你。 添加整合是您产品市场合适之旅中的昂贵的侧面任务。 如果价值支持足够好,他们将没有问题创建一个新的帐户并从头开始添加数据。 Accept that Pareto is right 换句话说,最后20%的任务需要80%的时间。 边缘案例和 gotchas 的表面随着实施而扩大。 谷歌的文件并非唯一会诱惑你认为事情可以简单和免费。 通过考虑回报,Idempotency,Fallback,Delta同步,离线,代币无效,配额和条件请求(ETags)来限制他们的承诺。 你不需要所有这些为你的MVP,但期望他们最终会出现。 Simplicity for one party means complexity for another 简单的UI →复杂的后端 对普通用户好,对电力用户困难 简单的价格 → 复杂的R&D 简单的 API → 复杂的集成 下次你想,“我只会使用这个免费的API,它看起来很简单,”记住: It’s either free or simple; Someone always pays. 现在去拿你的面包。