Java中的GraphQL Server,第I部分:基础知识

从表面上看,没有理由通常使用Node.js编写GraphQL服务器。但是,事实证明,不阻塞等待结果的基于回调的语言可以与GraphQL原理很好地配合。

在深入探讨为什么会发生这种情况之前,让我们首先了解GraphQL服务器在下面如何工作以及如何正确实现它。在第二部分中,我们将拆分实现以仅延迟加载必要的信息。在第三部分(最后一部分)中,我们将使用非阻塞惯用语重写服务器,以提高延迟和吞吐量。

什么是GraphQL?

首先,什么是GraphQL?我会说它位于REST和SOAP之间(很简单!)。这是一个相当轻量级的JSON协议,最适合浏览器和移动应用程序。就像REST一样。另一方面,它具有描述有效属性,操作和有效负载的架构。但是,与SOAP不同的是,该模式是为不断发展而设计的,并且我们对希望接收的数据范围拥有很好的控制权。

那里有很多GraphQL教程,所以让我直接跳到示例。这是描述一些API的相当简单的架构:

Java中的GraphQL Server,第I部分:基础知识

老实说,几乎没有什么可解释的。感叹号(!)表示非空字段(其他所有字段都是可选的)。方括号(如[Item]:)表示Items 的数组。这个非常简单的模式代表了一些在线游戏的对象图。

现在,我们需要某种此API的入口点。这与REST不同,后者的每个资源都有其URL。在GraphQL中,我们显式定义了一组允许查询的静态类型的操作:

Java中的GraphQL Server,第I部分:基础知识

该API仅将一个端点公开给fetch currentPlayer(返回Player实例),而从来没有null

使用GraphQL

GraphQL的独特之处在于可以选择Player我们感兴趣的属性。最完整的查询如下所示:

Java中的GraphQL Server,第I部分:基础知识

这将返回完整的JSON响应,匹配模式以及查询:

Java中的GraphQL Server,第I部分:基础知识

那很好笑!使用RESTful API,我只想简单地说/currentPlayer,服务器将返回类似的响应。为什么要在请求中大量复制架构呢?

这就是GraphQL的强大功能所在。想象一下,你只在玩家的名字和兴趣balance上的billing对象。您从服务器获得的所有额外信息都是多余的。使用RESTful接口,您可以选择:

  • 为每条信息设计细粒度的资源,这些信息将需要多次服务器往返
  • 提供服务于各种信息量的端点的多个版本。如果要精确,端点的数量呈指数增长
  • 忍受它,忽略客户端上的额外信息以及服务器上不必要的负载

GraphQL通过强制客户端明确要求某些信息来解决该问题。在我们的示例中,如果我们仅关注玩家的姓名和 balance

Java中的GraphQL Server,第I部分:基础知识

我们得到了先前响应的子集:

Java中的GraphQL Server,第I部分:基础知识

相反,如果另一个消费者需要知道库存物品的名称和点数怎么办?简单!

Java中的GraphQL Server,第I部分:基础知识

不同的客户,不同的需求:

Java中的GraphQL Server,第I部分:基础知识

实施服务器

实现GraphQL服务器仅在表面上类似于RESTful服务器。一个简单的实现只创建一个完整的响应对象,然后让GraphQL引擎将其剥离为仅由客户端请求的必要属性。这样的实现类似于信息非常丰富的RESTful端点。首先,我们需要一个与我们的模式一对一对应的DTO对象:

Java中的GraphQL Server,第I部分:基础知识

我们没有实现控制器,而是实现了所谓的Resolver

Java中的GraphQL Server,第I部分:基础知识

注意,为了组装Player实例,我们必须要求几个依赖项来获取数据。一个用于Billing,一个用于Inventory,依此类推。依赖关系彼此独立,但是都需要填充Player。此实现有效,并且如果/currentPlayer是RESTful端点,则可以称之为一天。但是,对于GraphQL,这种实现是一种反模式

顺便说一下,运行该程序的最小依赖项集(不包括Spring Boot本身)如下:

Java中的GraphQL Server,第I部分:基础知识

我将在上一期中提供完整的Spring Boot应用程序。

想象一下BillingRepository真的很慢。加载帐单太慢了,如果您不需要此信息,最好避免调用它。例如,此查询显式跳过计费数据:

Java中的GraphQL Server,第I部分:基础知识

即使弄清楚当前玩家的名字和分数是非常快的,你仍然要付出载入他或她的账单的代价。更糟的是,GraphQL引擎将剥离所有未请求的数据,因此会丢失额外的工作。在下一部分中将解释在合理的地方编写细粒度的解析器。

有什么问题可以加下qq:2062583349。也可添加vx:admindesire,有java、python、web等习资料和视频课程干货”。欢迎交流!