Spring for GraphQL 为基于 GraphQL Java 构建的 Spring 应用程序提供了支持。
本指南将引导您使用 Spring for GraphQL 在 Java 中创建 GraphQL 服务的过程。
您将构建的内容
您将构建一个服务,该服务将在 http://localhost:8080/graphql
接受 GraphQL 请求。
所需内容
-
大约15分钟
-
一个喜欢的文本编辑器或IDE
-
Java 17 或更高版本
-
您也可以直接将代码导入到您的 IDE 中:
如何完成本指南
与大多数 Spring 入门指南一样,您可以从头开始并完成每个步骤,也可以跳过您已经熟悉的基本设置步骤。无论哪种方式,您最终都能获得可运行的代码。
要从头开始,请继续阅读 使用 Spring Initializr 开始。
要跳过基础知识,请执行以下操作:
-
下载并解压本指南的源代码仓库,或使用 Git 克隆它:
git clone https://github.com/spring-guides/gs-graphql-server.git
-
进入
gs-graphql-server/initial
目录 -
直接跳转到 GraphQL 简介。
完成后,您可以将您的结果与 gs-graphql-server/complete
中的代码进行对比。
从 Spring Initializr 开始
如果您愿意,可以使用这个预填充的 Spring Initializr 链接来加载正确的配置。否则,请继续手动设置 Initializr。
要手动初始化项目:
-
访问 https://start.spring.io。该服务会为您拉取应用程序所需的所有依赖项,并完成大部分设置工作。
-
选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Java。
-
点击 Dependencies 并选择 Spring for GraphQL 和 Spring Web。
-
点击 Generate。
-
下载生成的 ZIP 文件,这是一个根据您的选择配置好的 GraphQL 应用程序的压缩包。
如果您的 IDE 集成了 Spring Initializr,您可以直接在 IDE 中完成此过程。
您也可以从 GitHub 上 fork 该项目,并在您的 IDE 或其他编辑器中打开它。
GraphQL 简要介绍
GraphQL 是一种用于从服务器检索数据的查询语言。它是 REST、SOAP 或 gRPC 的替代方案。在本教程中,我们将从一个在线商店后端查询特定书籍的详细信息。
这是一个您可以发送到 GraphQL 服务器以检索书籍详细信息的示例请求:
这个 GraphQL 请求表示:
-
查询 id 为 "book-1" 的书籍
-
对于书籍,返回 id、名称、页数和作者
-
对于作者,返回名字和姓氏
响应是 JSON 格式的。例如:
GraphQL 的一个重要特性是它定义了一种模式语言,并且是静态类型的。服务器确切地知道请求可以查询哪些类型的对象以及这些对象包含哪些字段。此外,客户端可以通过内省机制向服务器询问模式详细信息。
本教程中的 schema 一词指的是 "GraphQL Schema",它与 "JSON Schema" 或 "Database Schema" 等其他 schema 无关。
上述查询的架构为:
本教程将重点介绍如何使用此模式在 Java 中实现一个 GraphQL 服务器。
我们只是浅尝辄止地介绍了 GraphQL 的可能性。更多信息可以在 GraphQL 官方页面 找到。
我们的示例 API:获取书籍详情 {#_our_example_api_getting_book_details}
以下是使用 Spring for GraphQL 创建服务器的主要步骤:
-
定义 GraphQL 模式
-
实现获取查询实际数据的逻辑
我们的示例应用程序将是一个简单的API,用于获取特定书籍的详细信息。它并不是一个全面的API。
架构
在您之前准备好的 Spring for GraphQL 应用程序中,添加一个新文件 schema.graphqls
到 src/main/resources/graphql
文件夹,内容如下:
每个 GraphQL 模式都有一个顶层的 Query
类型,其下的字段是应用程序暴露的查询操作。这里的模式定义了一个名为 bookById
的查询,它会返回特定书籍的详细信息。
它还定义了带有字段 id
、name
、pageCount
和 author
的 Book
类型,以及带有字段 firstName
和 lastName
的 Author
类型。
上述用于描述模式的领域特定语言称为模式定义语言(SDL)。有关更多详细信息,请参阅 GraphQL 文档。
数据来源
GraphQL 的一个关键优势是数据可以从任何地方获取。数据可以来自数据库、外部服务或静态的内存列表。
为了简化教程,书籍和作者数据将来自它们各自类中的静态列表。
创建 Book 和 Author 数据源
现在让我们在主应用程序包中创建 Book
和 Author
类,就在 GraphQlServerApplication
旁边。使用以下内容作为它们的内容:
添加代码以获取数据
Spring for GraphQL 提供了一个基于注解的编程模型。通过使用控制器注解方法,我们可以声明如何获取特定 GraphQL 字段的数据。
将以下内容添加到主应用包中的 BookController.java
文件中,与 Book
和 Author
相邻:
通过在方法bookById
上添加@QueryMapping
注解,该控制器声明了如何根据Query类型定义的Book
进行获取。查询字段由方法名称决定,但也可以在注解本身中进行声明。
Spring for GraphQL 使用
RuntimeWiring.Builder
将每个此类控制器方法注册为 GraphQL Java 的graphql.schema.DataFetcher
。DataFetcher
提供了获取查询或任何模式字段数据的逻辑。GraphQL 的 Spring Boot 启动器包含自动配置,可以自动化此注册过程。
在 GraphQL Java 引擎中,DataFetchingEnvironment
提供了对字段特定参数值映射的访问。使用 @Argument
注解可以将参数绑定到目标对象并注入到控制器方法中。默认情况下,方法参数名称用于查找参数,但也可以在注解本身中指定。
这个 bookById
方法定义了如何获取特定的 Book
,但没有处理获取相关的 Author
。如果请求需要作者信息,GraphQL Java 将需要获取此字段。
@SchemaMapping
注解将处理程序方法映射到 GraphQL schema 中的字段,并声明它是该字段的 DataFetcher
。字段名称默认为方法名称,类型名称默认为注入到方法中的源/父对象的简单类名。在此示例中,字段默认为 author
,类型默认为 Book
。
更多信息,请参阅 Spring for GraphQL 注解控制器功能的文档。
这就是我们需要的所有代码!
让我们运行第一个查询。
运行我们的第一个查询
启用 GraphiQL Playground
GraphiQL 是一个用于编写和执行查询的有用可视化界面,功能非常丰富。通过将此配置添加到 application.properties
文件中来启用 GraphiQL。
启动应用程序
启动您的 Spring 应用程序。访问 http://localhost:8080/graphiql。
运行查询
输入查询内容,然后点击窗口顶部的播放按钮。
您应该会看到如下响应。
恭喜您,您已经构建了一个 GraphQL 服务并执行了您的第一个查询!在 Spring for GraphQL 的帮助下,您仅用几行代码就实现了这一点。
测试
Spring for GraphQL 在 spring-graphql-test
模块中提供了用于 GraphQL 测试的工具。我们已经在 Spring Initializr 生成的项目中包含了该模块。
全面测试一个 GraphQL 服务需要不同范围的测试。在本教程中,我们将编写一个 @GraphQlTest
切片测试,专注于单个控制器。还有其他工具可以帮助进行完整的端到端集成测试和聚焦的服务器端测试。有关完整细节,请参阅 Spring for GraphQL 测试文档 和 Spring Boot 文档中的 自动配置的 Spring for GraphQL 测试。
让我们编写一个控制器切片测试,用于验证刚才在 GraphiQL playground 中请求的相同 bookDetails
查询。
将以下内容添加到测试文件 BookControllerTests.java
中。将此文件保存在 src/test/java/com/example/graphqlserver/
文件夹内。
这个测试涉及到一个类似于我们在 GraphiQL Playground 中使用的 GraphQL 查询。它通过 $id
参数化,使其可重用。将此查询添加到位于 src/test/resources/graphql-test
目录下的 bookDetails.graphql
文件中。
运行测试并验证结果是否与在 GraphiQL Playground 中手动请求的 GraphQL 查询一致。
@GraphQlTest
注解对于编写专注于单个控制器的控制器切片测试非常有用。@GraphQlTest
会自动配置 Spring for GraphQL 的基础设施,而不涉及任何传输或服务器。自动配置使我们能够通过跳过样板代码来更快地编写测试。由于这是一个聚焦的切片测试,因此只会扫描有限数量的 Bean,包括 @Controller
和 RuntimeWiringConfigurer
。有关扫描的 Bean 列表,请参阅文档。
GraphQlTester
是一个声明了用于测试 GraphQL 请求的通用工作流的契约,它独立于传输方式。在我们的测试中,我们提供了一个带有 documentName
的文档以及所需的变量,然后 execute
执行该请求。接着,我们通过 JSON 路径选择响应的一部分,并断言该位置的 JSON 与预期结果匹配。
恭喜!在本教程中,您构建了一个 GraphQL 服务,运行了第一个查询,并编写了第一个 GraphQL 测试!
延伸阅读
示例源代码
本指南是与 GraphQL Java 团队合作编写的。特别感谢 Donna Zhou、Brad Baker 和 Andreas Marek!本教程的源代码可以在 GitHub 上找到。
文档
阅读 Spring for GraphQL 文档。
GraphQL Java 是驱动 Spring for GraphQL 的引擎。阅读 GraphQL Java 文档。
更多 Spring for GraphQL 示例
在1.0.x 分支中查看更多示例,这些示例将很快迁移到一个单独的仓库中。
Stack Overflow 问题
您可以在 Stack Overflow 上使用 spring-graphql 标签提出问题。