当前位置:网站首页 > Java教程 > 正文

graphql java教程



「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

GraphQL是一个从服务端检数据的查询语言。某种程度上,是REST、SOAP、或者gRPC的替代品。

假设我们要从在线商店的后台查询一本特定书记的详细信息。

使用GraphQL,你可以发送以下的查询到服务端来获取id为“book-1”的书籍的详细信息。

 

这不是JSON,虽然看起来很像。他是一个GraphQL查询语句。语句的含义是:

  • 查询指定id的一本书
  • 返回书籍的id、name、pageCount、author
  • 对于author字段,还需要包含firstName和lastName

返回结果是一个正常的JSON格式:

 

GraphQL一个非常重要的特性--它是静态类型的:服务端明确的知道你可以查询的每个对象的类型,客户端可以从服务端获取“schema”。Schema描述了哪些查询是可能的,哪些字段能被获取到。(注意:我们这里说的Schema指的是GraphQL Schema,他与其他Schema比如JSON Schema获取DataBase Schema无关)

上面查询的Schema如下所示:

 

这个教程将重点介绍如何使用Schema在java中实现一个GraphQL服务。

GraphQL Java是GraphQL的Java服务端的实现。在GraphQL Java Github org上有几个仓库。最重要的一个是GraphQL Java Engine(github.com/graphql-jav…

GraphQL Java Engine只关心查询的执行。它不处理任何HTTP或者JSON相关的事。基于这些方面,我们将用GraphQL Java Spring Boot适配器,它负责通过SpringBoot基于HTTP暴露我们的API。

创建一个GraphQL Java服务主要的步骤:

  1. 定义GraphQL Schema
  2. 决定一个查询如何获取到数据

我们的示例项目将会写一个简单的接口:获取指定书记的详细信息。虽然这不是一个全面的API,但对于本教程来说足够了。

导入3个包:

 

前2个是GraphQL Java和GraphQL Java Spring。Guava不是必要的,但是它能让我们更方便点。

在src/main/resources下面创建一个新文件schema.graphqls,写入一下内容:

 

这个Schema定义了一个顶级字段(在Query类型中):bookById,它返回指定熟记的详情。

它也定义了类型Book,包含字段:id,name,pageCount,author。author的类型是Author,这个在Book类型之后也定义了。

上面用来描述Schema的专用语言叫做Schema Definition Language 或者叫DSL。更多细节可以查看:graphql.org/learn/schem…

这个文件完成功后,我们就得使用它。

我们创建一个新的类GraphQLProvider,定义一个init方法,这个方法用来创建GraphQL实例:

 

我们使用Guava的Resources去读取之前创建的文件。接下来创建GraphQLSchema和GraphQL实例。这个GraphQL实例通过带有@Bean注解的graphQL()方法作为一个Spring Bean被暴露。GraphQL Java Spring适配器将使用GraphQL实例让我们的schema生效,通过HTTP,默认url: /graphql。

我们还需要做的就是实现buildSchema方法,该方法创建GraphQLSchema实例,连接sdl和DataFetcher。

 

TypeDefinitionRegistry是schema文件的解析版本。SchemaGenerator将TypeDefinitionRegistry和RuntimeWiring结合起来,生成GraphQLSchema。

buildWiring方法使用graphQLDataFetchers bean去注册2个。

  • 一个是通过指定id检索book
  • 一个是获取指定book的author

和如何实现 bean在下部分内容说明。

创建和实例总体过程如下所示: 创建过程

也许GraphQL Java server最重要的概念就是:在查询执行的时候,一个获取一个字段的数据。

当GraphQL Java在执行一个查询时,它会为查询语句中的每个字段调用合适的。一个是一个接口,其中只有一个方法,发发只有一个参数:

 

重点:schema中的每个字段都有一个与之关联。如果你没有给某个字段定义一个,那么会使用默认的。我们稍后会消息讨论这点。

我们接下来创建一个新类,它包含books和authors的样例list。

完整的实现如下所示:

 

我们从这个类中的静态列表里获取books和authors,这会帮助你理解GraphQL对数据来源没有任何要求。这是GraphQL的优势:数据可以来自内存里的静态数据,来自数据库或者外部服务。

我们第一个方法返回一个的实现--使用返回指定的book。这个例子的意思是,我们需要从字段拿到id参数,然后找到这个id对应的book。如果没有找到,返回null。

中的“id”指的是在schema中的query字段:

 

第二个方法,返回一个的实现--获取指定book的author。和book的DataFetcher方法比较,这个我们没有获取参数,但是我们有一个book的实例。通过方法可以获取到有效的父类字段,然后得到结果。这是一个重要的概念:GraphQL中每个字段的都是以自顶向下的方式被调用,父类的结果是子类的属性。

我们接下来使用前面获取的book拿到,然后使用和查询书相同的方式查询指定的author。

我们只实现了2个。正如前面提及的,如果你没有实现,那么就会使用默认的。按我们的例子来讲,意思就是说,,,,,都有一个默认的分别与之关联。

通过多种方式尝试在Java对象上获取属性。例子中很容易通过key查找属性。这对我们来说很好,因为book和Author的Maps的keys和schema中字段是一模一样的。比如,schema中我们定义Book类型的字段,book的返回的Map中有key . 因为字段名字和Map中的key一样,所以才能起作用。

让我们假设一下,我们有一个字段不匹配,book Map中的key是totalPages,而不是pageCount。这将会导致所有book的pageCount值为null,因为无法获取到正确的值。为了解决这个问题,你需要为Book.pageCount去注册一个新的,所下所示:

 

这就是构建GraphQL API所需要的全部内容。在运行SpringBoot项目后,使用地址下能看到API了。

尝试和查看GraphQL API最简单的方式是使用GraphQL Playground(www.graphql-java.com/tutorials/g…

启动之后你会要求输入一个URL,输入:http://localhost:8080/graphql

之后,你就可以查询我们之前写的样例API。

上面所讲的,引用了2个jar包,graphql-java是GraphQL的java实现形式。graphql-java-spring-boot-starter-webmvc是为了支持SpringWeb方式请求。

而graphql-java-kickstart是在这之上,不仅包含graphql-java,还有graphql-java-tools、graphql-java-servlet。支持了图形界面,我们只需要引入这一个依赖就可以了。

 

这两个都是graphql语法执行图形界面。

开启方式如下:

 

和之前所讲一样,需要创建schema文件,后缀必须是。

 

Schema中定义的每一个数据都需要有一个对应的Java对象:

 

和之前不一样的是,这个不需要我们写详细的解析步骤,只需要写一个Resolver。

 

@Component注解是为了被Spring发现。GraphQLQueryResolver接口是为了标记为Schema的解析类。方法名字必须和schema中定义的查询名字一样。

启动SpringBoot后,浏览器访问:http://localhost:8080/playground。就会进入图形界面 在这里插入图片描述

左边有2个按钮,DOCS和SCHEMA。DOCS会显示你定义的查询,以及可以获取到的详细信息。SCHEMA会显示你定义的SCHEMA。 在这里插入图片描述

在这里插入图片描述

如下所示,请求地址为:localhost:8080/graphql 请求方式为POST 参数为{"query":"graphql语句"} 在这里插入图片描述

  • 前端不需要多次请求,一次请求就可以获取所需数据
  • 前端自己决定需要获取的数据
  • API文件是及时更新的

语法:graphql.cn/learn/

源码:github.com/graphql-jav…

  • 上一篇: java内存划分教程
  • 下一篇: 新手学java教程
  • 版权声明


    相关文章:

  • java内存划分教程2025-03-20 18:58:02
  • java教程http2025-03-20 18:58:02
  • 兄弟java视频教程2025-03-20 18:58:02
  • idea java教程答案2025-03-20 18:58:02
  • java软件使用教程2025-03-20 18:58:02
  • 新手学java教程2025-03-20 18:58:02
  • java教程天码2025-03-20 18:58:02
  • java实战系列教程2025-03-20 18:58:02
  • java 文本教程2025-03-20 18:58:02
  • mac java开发视频教程2025-03-20 18:58:02