2015 年 9 月 14 日 由 Lee Byron 撰写
当我们构建 Facebook 的移动应用程序时,我们需要一个足够强大的数据获取 API 来描述整个 Facebook,同时又要简单易学,以便产品开发人员能够专注于快速构建产品。三年前,我们开发了 GraphQL 来满足这一需求。如今,它每天为数百亿个 API 调用提供支持。今年,我们开始通过起草规范、发布参考实现以及在 graphql.org 这里建立社区来开源 GraphQL。
早在 2012 年,我们就开始重建 Facebook 的原生移动应用程序。
当时,我们的 iOS 和 Android 应用程序只是我们移动网站视图的薄包装。虽然这让我们接近了“一次编写,随处运行”移动应用程序的理想状态,但在实践中,它将我们的移动网页应用程序推向了极限。随着 Facebook 移动应用程序变得越来越复杂,它们遭受了性能低下和频繁崩溃的困扰。
当我们过渡到原生实现的模型和视图时,我们发现自己第一次需要一个新闻提要的 API 数据版本——直到那时,它只作为 HTML 提供。我们评估了将新闻提要数据传递到我们的移动应用程序的选择,包括 RESTful 服务器资源和 FQL 表(Facebook 的类似 SQL 的 API)。我们对我们想要在应用程序中使用的数据与它们所需的服务器查询之间的差异感到沮丧。我们不以资源 URL、辅助键或联接表的方式思考数据;我们将其视为对象图以及我们在应用程序中最终使用的模型,例如 NSObjects 或 JSON。
在服务器上准备数据和在客户端上解析数据方面,还需要编写大量的代码。这种沮丧促使我们中的几个人开始了一个项目,最终成为了 GraphQL。GraphQL 是我们从产品设计师和开发人员的角度重新思考移动应用程序数据获取的机会。它将开发的重点转移到客户端应用程序,设计师和开发人员在那里花费时间和精力。
GraphQL 查询是一个发送到服务器的字符串,用于解释和执行,然后将 JSON 数据返回给客户端。
定义数据形状: 你会发现 GraphQL 查询与其响应相匹配。这使得预测查询返回的数据形状变得容易,并且如果你知道你的应用程序需要的数据,就可以轻松地编写查询。更重要的是,这使得 GraphQL 非常容易学习和使用。GraphQL 无疑地以产品以及构建产品的设计师和开发人员的数据需求为驱动。
分层结构: GraphQL 的另一个重要方面是其分层结构。GraphQL 自然地遵循对象之间的关系,而 RESTful 服务可能需要多次往返(在移动网络上资源密集型)或 SQL 中的复杂联接语句。这种数据层次结构与图结构数据存储以及最终用于其中的分层用户界面相匹配。
强类型: GraphQL 查询的每一层都对应于一个特定类型,每个类型描述一组可用的字段。类似于 SQL,这允许 GraphQL 在执行查询之前提供描述性错误消息。它也与 Obj-C 和 Java 的强类型原生环境相匹配。
协议,而非存储: 服务器上的每个 GraphQL 字段都由一个函数支持 - 连接到你的应用程序层的代码。当我们构建 GraphQL 来支持新闻提要时,我们已经拥有一个复杂的提要排名和存储模型,以及现有的数据库和业务逻辑。GraphQL 必须利用所有这些现有工作才能有用,因此它不规定或提供任何支持存储。相反,GraphQL 通过暴露你的应用程序层,而不是你的存储层,来利用你的现有代码。
内省: GraphQL 服务器可以被查询以获取其支持的类型。这为工具和客户端软件创建了一个强大的平台,可以在此信息之上构建,例如静态类型语言中的代码生成、我们的应用程序框架 Relay 或 IDE 如 GraphiQL(如下图所示)。GraphiQL 帮助开发人员快速学习和探索 API,而无需查看代码库或使用 cURL。
版本无关: 返回数据的形状完全由客户端的查询决定,因此服务器变得更简单且易于泛化。当您添加新的产品功能时,可以向服务器添加额外的字段,而不会影响现有客户端。当您停用旧功能时,相应的服务器字段可以被弃用,但仍能继续运行。这种渐进的向后兼容过程消除了对递增版本号的需求。我们仍然支持三个版本的 Facebook 应用程序,使用同一个版本的 GraphQL API。
使用 GraphQL,我们能够在 2012 年在 iOS 上构建完整的原生新闻提要,并在不久之后在 Android 上构建。从那时起,GraphQL 成为我们构建移动应用程序及其支持服务器的主要方式。三年多后,GraphQL 为我们几乎所有移动应用程序中的数据获取提供支持,每秒处理来自近 1000 个已发布应用程序版本的数百万个请求。
当我们在 2012 年构建 GraphQL 时,我们不知道它对我们在 Facebook 的构建方式会变得多么重要,也没有预料到它在 Facebook 之外的价值。然而,今年早些时候,我们宣布了 Relay,我们的基于 GraphQL 的 Web 和 React Native 应用程序框架。社区对 Relay 的热情激励我们重新审视 GraphQL,评估每个细节,进行改进,修复不一致之处,并编写一个规范来描述 GraphQL 及其工作原理。
两个月前,我们公开发布了我们的进展,并发布了 GraphQL 规范 的工作草案和一个参考实现:GraphQL.js。从那时起,一个围绕 GraphQL 的社区开始形成,并且 GraphQL 运行时的版本正在用多种语言构建,包括 Go、Ruby、Scala、Java、.Net 和 Python。我们还开始分享我们在内部使用的一些工具,例如GraphiQL,一个浏览器内 IDE、文档浏览器和查询运行器。GraphQL 也在 Facebook 之外得到了生产使用,在咨询公司 Red Badger 为 金融时报 的一个项目中使用。
“GraphQL 使数据获取的编排变得如此简单,它几乎可以作为前端和后端之间的完美隔离点。”——Red Badger 软件工程师 Viktor Charypar
虽然 GraphQL 是 Facebook 产品开发中已有的部分,但其在 Facebook 之外的使用才刚刚开始。尝试一下 GraphiQL 并帮助我们提供有关 规范 的反馈。我们认为 GraphQL 可以极大地简化客户端产品开发人员和服务器端工程师的数据需求,无论您在任何环境中使用什么语言,我们很高兴继续改进 GraphQL,帮助社区围绕它发展,并看看我们能一起构建什么。