GraphQL是什么

GraphQL是一种新的API标准,它提供了一种更高效、强大和灵活的数据提供方式。它是由Facebook开发和开源,目前由来自世界各地的大公司和个人维护。GraphQL本质上是一种基于api的查询语言,现在大多数应用程序都需要从服务器中获取数据,这些数据存储可能存储在数据库中,API的职责是提供与应用程序需求相匹配的存储数据的接口。有的人经常把GraphQL和数据库技术相混淆,这是一个误解,GraphQL是api的查询语言,而不是数据库。从这个意义上说,它是数据库无关的,而且可以在使用API的任何环境中有效使用,我们可以理解为GraphQL是基于API之上的一层封装,目的是为了更好,更灵活的适用于业务的需求变化。

GraphQL出现的历史背景

当提起API设计的时候,大家通常会想到SOAP,RESTful等设计方式,从2000年RESTful的理论被提出的时候,在业界引起了很大反响,因为这种设计理念更易于用户的使用,所以便很快的被大家所接受。我们知道REST是一种从服务器公开数据的流行方式。当REST的概念被提及出来时,客户端应用程序对数据的需求相对简单,而开发的速度并没有达到今天的水平。因此REST对于许多应用程序来说是非常适合的。然而在业务越发复杂,客户对系统的扩展性有了更高的要求时,API环境发生了巨大的变化。特别是从下面三个方面在挑战api设计的方式:
1.移动端用户的爆发式增长需要更高效的数据加载

Facebook开发GraphQL的最初原因是移动用户的增加、低功耗设备和松散的网络。GraphQL最小化了需要网络传输的数据量,从而极大地改善了在这些条件下运行的应用程序。

2.各种不同的前端框架和平台

前端框架和平台运行客户端应用程序的异构环境使得我们在构建和维护一个符合所有需求的API变得困难,使用GraphQL每个客户机都可以精确地访问它需要的数据。

3.在不同前端框架,不同平台下想要加快产品快速开发变的越来越难

持续部署已经成为许多公司的标准,快速的迭代和频繁的产品更新是必不可少的。对于REST api,服务器公开数据的方式常常需要修改,以满足客户端的特定需求和设计更改。这阻碍了快速开发实践和产品迭代。

GraphQL的出现不仅仅是针对开发人员的,Facebook在2012年开始在其native mobile apps中使用GraphQL。但有趣的是GraphQL大部分都是在web技术的背景下使用的,并且在native mobile 领域中只得到很少的支持。 Facebook第一次公开谈论GraphQL是在宣布开源计划后不久的2015年React峰会的时候。因为Facebook总是在React的背景下谈GraphQL,所以对于没有React经验的开发人员来说,要理解GraphQL并不是一种仅限于React使用的技术可能还需要一段时间。即便是在这样的背景下诞生的GraphQL依然是一个快速增长的社区 ,事实上GraphQL是一种技术,可以在客户端与API通信的任何地方使用。有趣的是Netflix和Coursera等其他公司都在研究类似的想法以提高API的交互效率。Coursera设想了一种类似的技术,可以让客户指定其数据需求,而Netflix甚至将其解决方案称为Falcor。在GraphQL被开源之后,Coursera完全停止了他们在Falcor上的努力,并转到了GraphQL的学习上。目前已经有很多的公司在使用GraphQL(https://graphql.org/users/)。

GraphQL和RESTful的区别

前面提到GraphQL可以理解为基于RESTful的一种封装,目的在于构建使Client更加易用的服务,可以说GraphQL是更好的RESTful设计。在过去的十多年中,REST已经成为设计web api的标准(虽然只是一个模糊的标准)。它提供了一些很棒的想法,比如无状态服务器和结构化的资源访问。然而REST api表现得过于僵化,无法跟上访问它们的客户的快速变化的需求。 GraphQL的开发是为了应付更多的灵活性和效率,它解决了与REST api交互时开发人员所经历的许多缺点和低效之处。 为了说明在从API获取数据时REST和GraphQL之间的主要区别,让我们考虑一个简单的示例场景:在blog应用程序中,应用程序需要显示特定用户的文章的标题。同一屏幕还显示该用户最后3个关注者的名称。REST和GraphQL如何解决这种情况?

使用REST API来现实时,我们通常可以通过访问多次请求来收集数据。比如在这个示例中,我们可以通过下面的三步来实现:

1. 通过 /user/<id>获取初始用户数据

2. 通过/user/<id>/posts 返回用户的所有帖子

3. 请求/user/<id>/followers,返回每个用户的关注者列表

调用关系如下图所示:

如果用GraphQL的话,我们只需要一次请求就可以完成上述的需求

在GraphQL的世界里我们不用多取数据,也不用担心数据取少了,我们只需要按需获取即可。

REST最常见的问题之一是API的返回数据过多或者过少,这是因为客户端下载数据的唯一方法是通过访问返回固定数据结构的endpoint,这就会导致我们设计API非常困难,因为它既要能够为客户提供精确的数据需求,又需要满足不同调用者的需求,这本身就是相互矛盾的。GraphQL的发明者Lee Byron提出了一个很重要的概念: “用图形来思考,而不是endpoint”

通过上述直观展示我们可以得出一下几点:

1. 获取了许多多余的数据

通常情况下我们在调用一个通用API接口时,客户端获取的信息比应用程序中实际需要的要多。例如UI需要显示一个用户列表,而实际上只需要使用他们的名字。在REST API中通常会调用 /user 这个endpoint,并接收一个带有用户数据的JSON数组。但是这个响应可能包含更多关于返回的用户的信息,例如他们的生日或地址,而这些信息对客户来说是无用的,因为它只需要显示用户的名字。

2. 获取的数据少于Client所需要的数据

一般来说数据获取不足意味着某个特定的endpoint 没有提供客户端需要的足够信息,客户端将需要额外的请求来获取它所需要的一切。这可能会升级到客户端需要首先获取列表信息,然后需要对单条数据添加一个额外的请求以获取其他所需的数据,例如考虑其他Client 也需要显示每个用户的最后三个关注者,该API提供了额外的endpoint  /user/<userid>/followers,为了能够显示所需的信息,Client 必须向 /users endpoint 发出一个请求,然后点击/user/<user-id>/follwers endpoint 来获取单个用户的follwers信息。

3. 前端的快速产品迭代对API有很大的挑战

REST api的一个常见模式是根据你在应用程序内部的展现逻辑来构造endpoint,这很方便,因为它允许客户端通过访问相应的endpoint获取特定视图的所有所需信息。 这种方法的主要缺点是它不允许前端的快速迭代。对于UI所做的每一个更改,现在都存在比以前更多(或更少)的数据的高风险。因此,需要对后端进行调整,以满足新的数据需求,这会降低生产力并显著降低将用户反馈集成到产品中的能力。 使用GraphQL这个问题就解决了。由于GraphQL的灵活性,无需在服务器上额外工作就可以在客户端上进行更改。由于客户端可以指定准确的数据需求,所以当前端的设计和数据需求发生变化时,并不需要后端API做出任何的修改就可以满足展现层的变化。

 4. Schema和类型系统的好处

GraphQL使用强大的Type System来定义API的功能。所有在API中公开的类型都是使用GraphQL schema Definition Language (SDL)在模式中编写的。该模式充当客户端和服务器之间的契约,以定义客户机如何访问数据。 一旦定义了模式,在前端和后端工作的团队就可以在没有进一步通信的情况下完成工作,因为他们都知道通过网络发送的数据的确切结构。 前端团队可以通过mock所需的数据结构来轻松测试他们的应用程序。一旦后端API实现完成,就可以对客户端应用程序进行切换来调用实际的API获取数据,这也可以使得我们实现更好的客户端和服务端的分离。

我们可以看出GraphQL的出现可以使得我们后端API具有更大的灵活性以及扩展性以满足不同client对数据的需要,这大大丰富了API的数据提供的能力。

GraphQL 的前世今生的更多相关文章

  1. 让ASP.NET Core支持GraphQL之-GraphQL的实现原理

    众所周知RESTful API是目前最流行的软件架构风格之一,它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制. RESTful的优越性是毋庸置疑 ...

  2. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  3. [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性

    回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...

  4. docker4dotnet #1 – 前世今生 & 世界你好

    作为一名.NET Developer,这几年看着docker的流行实在是有些眼馋.可惜的是,Docker是基于Linux环境的,眼瞧着那些 java, python, node.js, go 甚至连p ...

  5. Atitit 智能云网络摄像机的前世今生与历史 优点  密码默认888888

    Atitit 智能云网络摄像机的前世今生与历史 优点  密码默认888888 用户名admin  密码aaaaaa 网络摄像机是一种结合传统摄像机与网络技术所产生的新一代摄像机,它可以将影像通过网络传 ...

  6. Facebook的Web开发三板斧:React.js、Relay和GraphQL

    2015-02-26 孙镜涛  InfoQ Eric Florenzano最近在自己的博客上发表了一篇题为<Facebook教我们如何构建网站>的文章,他认为软件开发有些时候需要比较大的跨 ...

  7. 阿里开源消息中间件RocketMQ的前世今生-转自阿里中间件

    昨天,我们将分布式消息中间件RocketMQ捐赠给了开源软件基金会Apache. 孵化成功后,RocketMQ或将成为国内首个互联网中间件在Apache上的顶级项目. 消息一出,本以为群众的反应是这样 ...

  8. JavaScript的前世今生

    和CSS一样,JavaScript在各浏览器下并非完全一致,它所带来的兼容性问题时常困扰着我们,以至于现在“能否处理流行浏览器的兼容性问题”成为了检验一个程序员是否合格的标准之一.了解JavaScri ...

  9. 主成分分析PCA的前世今生

    这篇博客会以攻略形式介绍PCA在前世今生. 其实,主成分分析知识一种分析算法,他的前生:应用场景:后世:输出结果的去向,在网上的博客都没有详细的提示.这里,我将从应用场景开始,介绍到得出PCA结果后, ...

随机推荐

  1. fiddler安装 与 https

    1.下载最新版fiddler ,强烈建议在官网下载:https://www.telerik.com/download/fiddler 2. 正常傻瓜式安装,下一步,下一步,安装完毕后,先不用急于打开软 ...

  2. 1.3 正则表达式和python语言-1.3.4使用 match()方法匹配字符串

    1.3.4使用 match()方法匹配字符串(第一次写博客,格式,述语有不当之处还请见谅)2018-05-08 Python 代码是以Jupyter Notebook编写的,主要写的是python3的 ...

  3. On the Optimal Approach of Survivable Virtual Network Embedding in Virtualized SDN

    Introduction and related work 云数据中心对于虚拟技术是理想的创新地方. 可生存性虚拟网络映射(surviavable virtual network embedding ...

  4. PyQt4转换ui为py文件需添加如下代码才可执行

    1)转换ui为py 命令行进入ui文件所在文件夹,输入pyuic4 ui_name.ui > py_name.py即可 或新建ui2py.bat文件,写入: @echo off @cd /d & ...

  5. Markdown常用快捷键

    Markdown使用的符号:井号,星号,大于号,中括号,竖线,横杠,波浪线,反引号 # ,*, > ,[],|,-,~,` 井号 + 空格:根据空格的个数显示各标题的大小 标题一 标题二 标题三 ...

  6. 关于外网无法访问阿里云主机CentOs

    前两天阿里云ECS搞活动,所有买了个三年的Ecs,然后照着之前在虚拟机同样的搭建服务器,一切都很正常,可是 当我配置好防火墙和nginx之后,发现个问题,外网无法访问. 思考: 1.我的nginx没配 ...

  7. vue百度地图插件

    安装 npm i --save vue-baidu-map 代码 <template> <div> <baidu-map v-bind:style="mapSt ...

  8. nginx + springboot 配置

    1.spring boot 访问地址http://localhost:13000/test/hello 2.配置nginx.conf文件 upstream my_ngix { server local ...

  9. java学习之路--零碎的知识笔记

    java运算符: 自增自减运算符: int b = ++a; 拆分运算过程为: a=a+1=4; b=a=4, 最后结果为b=4,a=4 前缀自增自减法(++a,--a): 先进行自增或者自减运算,再 ...

  10. scala 2.11.x/spec/03-types.md

    scala/spec/03-types.md title: Types layout: default chapter: 3 --- Types Type ::= FunctionArgTypes ' ...