Spring for GraphQL
如果你想构建 GraphQL 应用程序,你可以利用 Spring Boot 的自动配置,即 Spring for GraphQL。Spring for GraphQL 项目基于 GraphQL Java。你至少需要 spring-boot-starter-graphql
启动器。由于 GraphQL 与传输无关,你还需要在你的应用程序中安装一个或多个其他启动器,以便通过网络公开你的 GraphQL API
启动器 | 传输 | 实现 |
---|---|---|
|
HTTP |
Spring MVC |
|
WebSocket |
Servlet 应用程序的 WebSocket |
|
HTTP、WebSocket |
Spring WebFlux |
|
TCP、WebSocket |
Reactor Netty 上的 Spring WebFlux |
GraphQL 模式
Spring GraphQL 应用程序在启动时需要一个已定义的模式。默认情况下,你可以在 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 RuntimeWiring
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 存储库
-
QuerydslPredicateExecutor
-
ReactiveQuerydslPredicateExecutor
-
QueryByExampleExecutor
-
ReactiveQueryByExampleExecutor
会被 Spring Boot 检测到,并被视为匹配顶级查询的 DataFetcher
的候选者。
传输
HTTP 和 WebSocket
默认情况下,GraphQL HTTP 端点位于 HTTP POST /graphql
。它还支持仅用于订阅的服务器发送事件的 "text/event-stream"
媒体类型。路径可以通过 spring.graphql.path
进行自定义。
Spring MVC 和 Spring WebFlux 的 HTTP 端点由 @Order 为 0 的 RouterFunction bean 提供。如果你定义了自己的 RouterFunction bean,则可能需要添加适当的 @Order 注解以确保正确排序。
|
默认情况下,GraphQL WebSocket 端点处于关闭状态。要启用它
-
对于 Servlet 应用程序,添加 WebSocket starter
spring-boot-starter-websocket
-
对于 WebFlux 应用程序,不需要其他依赖项
-
对于两者,都必须设置
spring.graphql.websocket.path
应用程序属性
Spring GraphQL 提供了一个 Web 拦截 模型。这对于从 HTTP 请求头中检索信息并将其设置在 GraphQL 上下文中,或从同一上下文中获取信息并将其写入响应头非常有用。使用 Spring Boot,你可以声明一个 WebInterceptor
bean,以便将其注册到 Web 传输中。
Spring MVC 和 Spring WebFlux 支持 CORS(跨域资源共享)请求。CORS 是从使用不同域的浏览器访问 GraphQL 应用程序的 Web 配置的关键部分。
Spring Boot 支持 spring.graphql.cors.*
命名空间下的许多配置属性;以下是一个简短的配置示例
-
属性
-
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
组件。异常必须解析为 graphql.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 模式。