如何有效处理日益增长不断变化的Web/Mobile端复杂的数据需求。个人认为,REST原论文最大的功劳在于前后端分离与无状态请求,而REST的资源化的请求方式只适合面向简单的请求,对于具有复杂资源间关联的请求就有点无能为力。
目录
为何需要GraphQL
- 需要进行多次往返以获取视图所需的数据:REST API最大的问题是其多端点的本质(每个端点代表一个资源),这要求客户端进行多次往返以获取数据。而GraphQL,你可以随时通过单次往返服务器获取视图所需的所有初始数据。
- 客户端依赖于服务端:REST API中没有客户端请求语言(需要引入难以管理和扩展的非结构化参数和条件)。而GraphQL 使用它作为请求语言:(1) 消除了服务器对数据形状或大小进行硬编码的需要,(2) 将客户端与服务端分离。这意味着我们可以把客户端与服务端分离开来,单独进行维护和改进。
- 糟糕的前端开发体验:REST API中客户端无法控制服务器返回的数据,这对客户端和服务器而言都是网络和内存资源的浪费。使用GraphQL开发人员可以声明式地来表达其用户界面的数据需求。他们声明他们需要什么数据,而不是如何获取它。
- 代码冗余严重:REST API的另一大问题是版本控制,如果需要支持多个版本,那通常意味着需要新的端点,这可能导致服务器上的代码冗余。
前言
- 2015 React欧洲大会上,Lee Byron介绍了Facebook的 GraphQL ,包含GraphQL背后的故事,查询语句的示例,还有核心的概念。
- GraphQL与之前Netflix出品的Falcor,都是致力于解决相同的问题。
- Facebook用了GraphQL做了第一款真正的本地移动应用,现在应用每天会接受 260 亿的请求。
介绍
- GraphQL并不是一个面向图数据库的查询语言,而是一个数据抽象层,包括数据格式、数据关联、查询方式定义与实现等等一揽子的东西。这个抽象层可以用任意语言编写,它定义了一个通用的基于图形的 schema 来发布它所代表的数据服务的功能。使用 GraphQL 的客户端程序可以通过其功能查询该 schema。这种方法使得客户端与服务端解耦,并允许其两者独立开发和扩展。
- GraphQL 请求可以是查询(读取操作)或突变(写入操作)。对于这两种情况,请求都是一个简单的字符串,GraphQL 服务可以使用指定格式的数据解释,执行和解析。通常用于移动和 Web 应用的响应格式为 JSON。
核心概念
- GraphQL schema 是强类型 schema。要创建一个 GraphQL schema,我们要定义具有类型的字段。这些类型可以是原语的或者自定义的,并且 schema 中的所有其他类型都需要类型。这种丰富的类型系统带来丰富的功能,如拥有内省 API,并能够为客户端和服务器构建强大的工具。
- GraphQL 使用图与数据通信,数据自然是图。如果需要表示任何数据,右侧的结构便是图。GraphQL 运行时允许我们使用与该数据的自然图形式匹配的图 API 来表示我们的数据。
- GraphQL 具有表达数据需求的声明性。GraphQL 为客户端提供了一种声明式语言,以便表达它们的数据需求。这种声明性创造了一个关于使用 GraphQL 语言的内在模型,它接近于我们用英语考虑数据需求的方式,并且它让使用 GraphQL API 比备选方案(REST API)容易得多。
java实践
jdk1.8以上才支持。
graphql-java定义了两种schema语言,一种是标准的java语言的,一种是[IDL](),类似json格式的语言;
- IDL(个人的理解是用于前端)
type helloWorldQuery {
hello: String
}
- Java(个人理解是用于后台)
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>3.0.0</version>
</dependency>
GraphQLObjectType queryType = newObject()
.name("helloWorldQuery")
.field(newFieldDefinition()
.type(GraphQLString)
.name("hello")
.staticValue("world"))
.build();
GraphQLSchema schema = GraphQLSchema.newSchema()
.query(queryType)
.build();
GraphQL graphQL = GraphQL.newGraphQL(schema).build();
Map<String, Object> result = graphQL.execute("{hello}").getData();
System.out.println(result);
// Prints: {hello=world}
QA
- 为什么客户端不直接与服务器通信呢?
在客户端和服务器之间加入GraphQL层的考量有多种原因。其中之一,也许是最受欢迎的原因便是效率。客户端通常需要向服务器请求多个资源,而服务器会用单个资源进行响应。所以客户端的请求最终会多次往返服务器,以收集所有需要的数据。使用 GraphQL,我们基本上可以将这种多个请求的复杂度转移到服务器端,并且通过 GraphQL 层处理它。客户端向 GraphQL 层发起单个请求,并获得一个完全符合客户端需求的响应。