GraphQL:一种数据查询语言
当我们构建 Facebook 的移动应用程序时,我们需要一个足够强大以描述整个 Facebook,但又足够简单易学的数据获取 API,以便产品开发人员可以专注于快速构建功能。我们三年前开发了 GraphQL 来满足这一需求。如今,它每天支撑着数千亿次的 API 调用。今年,我们已开始通过起草规范、发布参考实现以及在此处graphql.org建立社区来开源 GraphQL 的过程。
为什么选择 GraphQL?
早在 2012 年,我们就开始着手重建 Facebook 的原生移动应用程序。
当时,我们的 iOS 和 Android 应用是围绕我们移动网站视图的薄封装层。虽然这使我们接近“编写一次,随处运行”移动应用的柏拉图式理想,但在实践中,它将我们的移动 WebView 应用推向了极限。随着 Facebook 移动应用的日益复杂,它们遭受了性能不佳和频繁崩溃的问题。
当我们转向原生实现的模型和视图时,我们第一次发现需要一个新闻源(News Feed)的数据 API 版本——新闻源在此之前只以 HTML 形式提供。我们评估了向移动应用提供新闻源数据的选项,包括 RESTful 服务器资源和 FQL 表(Facebook 的类 SQL API)。我们对应用中想要使用的数据与所需的服务器查询之间的差异感到沮丧。我们不会根据资源 URL、次键或连接表来思考数据;我们会从对象图和最终在应用中使用的模型(如 NSObject 或 JSON)的角度来思考。
服务器端准备数据和客户端解析数据都需要编写大量的代码。这种挫败感促使我们中的一些人启动了最终成为 GraphQL 的项目。GraphQL 是我们从产品设计师和开发人员的角度重新思考移动应用数据获取的机会。它将开发重点转移到了客户端应用程序上,这是设计师和开发人员花费时间和精力的地方。
什么是 GraphQL?
GraphQL 查询是一个发送到服务器进行解释和满足的字符串,服务器然后返回 JSON 给客户端。
定义数据形状: 您首先会注意到的是,GraphQL 查询与其响应相匹配。这使得很容易预测查询返回的数据的形状,以及在您知道应用所需数据时编写查询。更重要的是,这使得 GraphQL 非常容易学习和使用。GraphQL 是完全由产品的需求以及构建它们的设计师和开发人员的需求所驱动的。
层次结构: GraphQL 的另一个重要方面是其层次结构特性。GraphQL 自然地遵循对象之间的关系,而 RESTful 服务可能需要多次往返(对移动网络来说资源密集)或在 SQL 中使用复杂的连接语句。这种数据层次结构与图结构数据存储非常匹配,最终也与它所使用的分层用户界面非常匹配。
强类型: GraphQL 查询的每个级别都对应一个特定的类型,每个类型描述了一组可用的字段。与 SQL 类似,这使得 GraphQL 能够在执行查询之前提供描述性的错误消息。它也与 Obj-C 和 Java 的强类型原生环境配合良好。
协议,而非存储: GraphQL 服务器上的每个字段都由一个函数支持——连接到应用程序层的代码。虽然我们构建 GraphQL 是为了支持新闻源,但我们已经有了一个复杂的源排序和存储模型,以及现有的数据库和业务逻辑。GraphQL 必须利用所有这些现有工作才能发挥作用,因此它不规定或提供任何底层存储。相反,GraphQL 通过暴露您的应用程序层而不是存储层来利用您现有的代码。
自省: 可以查询 GraphQL 服务器以了解其支持的类型。这为工具和客户端软件在此信息之上构建提供了强大的平台,例如静态类型语言中的代码生成、我们的应用框架 Relay 或 GraphiQL 等 IDE(如下所示)。GraphiQL 帮助开发人员快速学习和探索 API,而无需抓取代码库或摆弄 cURL。
无版本: 返回数据的形状完全由客户端的查询决定,因此服务器更简单且易于泛化。当您添加新的产品功能时,可以向服务器添加额外的字段,而不会影响现有客户端。当您停用旧功能时,相应的服务器字段可以被弃用但仍能正常工作。这种渐进的、向后兼容的过程消除了对递增版本号的需要。我们仍然在单个版本的 GraphQL API 上支持发布了三年的 Facebook 应用程序。
有了 GraphQL,我们能够在 2012 年在 iOS 上构建功能齐全的原生新闻源,并在 Android 上紧随其后。从那时起,GraphQL 已成为我们构建移动应用及其支持服务器的主要方式。三年多过去了,GraphQL 支撑着我们移动应用中几乎所有的数据获取,从近 1,000 个已发布的应用程序版本中提供每秒数百万次的请求。
当我们于 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 使数据获取的编排变得更加简单,它几乎充当了前端和后端之间的完美隔离点”—— Viktor Charypar,Red Badger 软件工程师
虽然 GraphQL 已成为在 Facebook 构建产品中既定的一部分,但其在 Facebook 之外的应用才刚刚开始。请尝试GraphiQL,并就我们的规范提供反馈。我们认为,无论您在任一环境中使用的语言是什么,GraphQL 都可以极大地简化客户端产品开发人员和服务器端工程师的数据需求,我们很高兴能继续改进 GraphQL,帮助围绕它建立社区,并期待我们共同创造的成果。