|
如需获取最新稳定版本,请使用 Spring Boot 4.0.4! |
Spring for GraphQL
如果您希望构建 GraphQL 应用程序,可以利用 Spring Boot 对 Spring for GraphQL 的自动配置功能。
Spring for GraphQL 项目基于 GraphQL Java。
您至少需要引入 spring-boot-starter-graphql Starters。
由于 GraphQL 与传输协议无关,您还需要在应用程序中引入一个或多个其他Starters,以便通过 Web 暴露您的 GraphQL API:
| Starters | 传输 | 实现 |
|---|---|---|
|
HTTP |
Spring MVC |
|
WebSocket |
Servlet 应用的 WebSocket |
|
HTTP、WebSocket |
Spring WebFlux |
|
TCP、WebSocket |
基于 Reactor Netty 的 Spring WebFlux |
GraphQL 模式
Spring GraphQL 应用在启动时需要定义一个模式(schema)。
默认情况下,您可以在 src/main/resources/graphql/** 目录下编写以 ".graphqls" 或 ".gqls" 为扩展名的模式文件,Spring Boot 将自动加载这些文件。
您可以通过 spring.graphql.schema.locations 自定义模式文件的存放位置,并通过 spring.graphql.schema.file-extensions 自定义文件扩展名。
如果希望 Spring Boot 在应用程序的所有模块及依赖项中检测该位置的模式文件,可将 spring.graphql.schema.locations 设置为 "classpath*:graphql/**/"(注意其前缀为 classpath*:)。 |
在接下来的章节中,我们将以如下示例 GraphQL 模式为例,该模式定义了两种类型和两个查询:
type Query {
greeting(name: String! = "Spring"): String!
project(slug: ID!): Project
}
""" A Project in the Spring portfolio """
type Project {
""" Unique string id used in URLs """
slug: ID!
""" Project name """
name: String!
""" URL of the git repository """
repositoryUrl: String!
""" Current support status """
status: ProjectStatus!
}
enum ProjectStatus {
""" Actively supported by the Spring team """
ACTIVE
""" Supported by the community """
COMMUNITY
""" Prototype, not officially supported yet """
INCUBATING
""" Project being retired, in maintenance mode """
ATTIC
""" End-Of-Lifed """
EOL
}
默认情况下,字段内省将在模式中启用,因为 GraphiQL 等工具需要此功能。
如果您不希望公开有关模式的信息,可通过将 spring.graphql.schema.introspection.enabled 设置为 false 来禁用内省功能。 |
GraphQL 运行时绑定
GraphQL Java RuntimeWiring.Builder 可用于注册自定义标量类型、指令、类型解析器、DataFetcher 等。
您可在 Spring 配置中声明 RuntimeWiringConfigurer Bean,以获取对 RuntimeWiring.Builder 的访问权限。
Spring Boot 会自动检测此类 Bean,并将其添加到 GraphQlSource 构建器 中。
然而,应用程序通常不会直接实现 DataFetcher,而是创建带注解的控制器。
Spring Boot 会自动检测带有注解处理器方法的 @Controller 类,并将这些类注册为 DataFetcher 实例。
以下是我们问候查询的一个示例实现,使用了 @Controller 类:
-
Java
-
Kotlin
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
@Controller
public class GreetingController {
@QueryMapping
public String greeting(@Argument String name) {
return "Hello, " + name + "!";
}
}
import org.springframework.graphql.data.method.annotation.Argument
import org.springframework.graphql.data.method.annotation.QueryMapping
import org.springframework.stereotype.Controller
@Controller
class GreetingController {
@QueryMapping
fun greeting(@Argument name: String): String {
return "Hello, $name!"
}
}
Querydsl 与 QueryByExample 仓库支持
Spring Data 提供对 Querydsl 和 QueryByExample 仓库的支持。
Spring GraphQL 可以 将 Querydsl 和 QueryByExample 仓库配置为 DataFetcher。
使用 @GraphQlRepository 注解并继承以下接口之一的 Spring Data 仓库:
由 Spring Boot 检测到,并被视为用于匹配顶层查询的 DataFetcher 的候选者。
传输
HTTP 和 WebSocket
GraphQL HTTP 端点默认位于 HTTP POST /graphql。
它还仅针对订阅功能,通过服务器发送事件(Server-Sent Events)支持 "text/event-stream" 媒体类型。
该路径可通过 spring.graphql.http.path 进行自定义。
Spring MVC 和 Spring WebFlux 的 HTTP 端点均由一个 RouterFunction 类型的 Bean 提供,该 Bean 的 @Order 为 0。
如果您自行定义了 RouterFunction 类型的 Bean,则可能需要添加适当的 @Order 注解,以确保它们被正确排序。 |
GraphQL WebSocket 端点默认处于关闭状态。如需启用,请执行以下操作:
-
对于 Servlet 应用程序,请添加 WebSocket Starters
spring-boot-starter-websocket -
对于 WebFlux 应用程序,无需额外依赖。
-
对于两者,都必须设置
spring.graphql.websocket.path应用程序属性
Spring GraphQL 提供了一种 Web 拦截 模型。
该模型对于从 HTTP 请求头中获取信息并将其设置到 GraphQL 上下文中,或从同一上下文中获取信息并将其写入响应头,非常有用。
在 Spring Boot 中,您可以声明一个 WebGraphQlInterceptor Bean,以便将其注册到 Web 传输层。
Spring MVC 和 Spring WebFlux 支持 CORS(跨域资源共享)请求。 对于通过浏览器从不同域名访问的 GraphQL 应用程序而言,CORS 是其 Web 配置中至关重要的一部分。
Spring Boot 在 spring.graphql.cors.* 命名空间下支持许多配置属性;以下是一个简短的配置示例:
-
Properties
-
YAML
spring.graphql.cors.allowed-origins=https://example.org
spring.graphql.cors.allowed-methods=GET,POST
spring.graphql.cors.max-age=1800s
spring:
graphql:
cors:
allowed-origins: "https://example.org"
allowed-methods: GET,POST
max-age: 1800s
RSocket
RSocket 也支持作为传输协议,可基于 WebSocket 或 TCP 运行。
配置好 RSocket 服务器 后,我们即可使用 spring.graphql.rsocket.mapping 在特定路由上配置 GraphQL 处理器。
例如,将该映射配置为 "graphql",意味着在使用 RSocketGraphQlClient 发送请求时,可将其用作路由。
Spring Boot 会自动配置一个 RSocketGraphQlClient.Builder<?> Bean,您可以在自己的组件中注入该 Bean:
-
Java
-
Kotlin
@Component
public class RSocketGraphQlClientExample {
private final RSocketGraphQlClient graphQlClient;
public RSocketGraphQlClientExample(RSocketGraphQlClient.Builder<?> builder) {
this.graphQlClient = builder.tcp("example.spring.io", 8181).route("graphql").build();
}
@Component
class RSocketGraphQlClientExample(private val builder: RSocketGraphQlClient.Builder<*>) {
然后发送一个请求: include-code::RSocketGraphQlClientExample[tag=request]
异常处理
Spring GraphQL 使应用程序能够注册一个或多个 Spring DataFetcherExceptionResolver 组件,这些组件将按顺序被调用。
该异常必须被解析为一个 GraphQLError 对象列表,请参阅 Spring GraphQL 异常处理文档。
Spring Boot 将自动检测 DataFetcherExceptionResolver Bean 并将其注册到 GraphQlSource.Builder 中。
GraphiQL 和模式打印器
Spring GraphQL 为开发人员在使用或开发 GraphQL API 时提供基础设施支持。
Spring GraphQL 提供了一个默认的 GraphiQL 页面,默认在 "/graphiql" 路径下提供。
该页面默认处于禁用状态,可通过配置 spring.graphql.graphiql.enabled 属性来启用。
许多公开此类页面的应用程序更倾向于使用自定义构建版本。
默认实现对于开发阶段非常有用,因此在使用 spring-boot-devtools 进行开发时会自动启用该页面。
您还可以在启用 spring.graphql.schema.printer.enabled 属性时,以文本格式在 /graphql/schema 处公开 GraphQL 模式。