GraphQL 为 Spring 提供支持
如果你想构建 GraphQL 应用程序,可以利用 Spring Boot 为 Spring for GraphQL 提供的自动配置功能。
Spring for GraphQL 项目基于 GraphQL Java 构建。
你至少需要引入 spring-boot-starter-graphql 起步依赖。
由于 GraphQL 与传输协议无关,因此你还需要在应用程序中添加一个或多个额外的起步依赖,以便通过 Web 暴露你的 GraphQL API:
| starter | 运输 | 实施 |
|---|---|---|
|
HTTP |
Spring MVC |
|
WebSocket |
WebSocket for Servlet apps |
|
HTTP, WebSocket |
Spring WebFlux |
|
TCP, WebSocket |
Spring WebFlux 与 Reactor Netty |
GraphQL 模式
Spring GraphQL应用在启动时需要定义一个模式。
默认情况下,您可以在src/main/resources/graphql/**下编写".graphqls"或".gqls"模式文件,并且Spring Boot会自动识别它们。
您可以使用spring.graphql.schema.locations自定义位置,并使用spring.graphql.schema.file-extensions自定义文件扩展名。
如果要让 Spring Boot 在整个应用程序模块和依赖项中检测 schema 文件,请将 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
}
By default, 字段 introspection 将被允许在模式上,因为这对于像 GraphiQL 这样的工具是必需的。
如果希望不暴露模式信息,可以通过设置 spring.graphql.schema.introspection.enabled 为 false 来禁用 introspection。 |
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 仓库:
由 Spring Boot 检测并视为用于匹配顶层查询的 DataFetcher 候选项。
传输方式
HTTP 和 WebSocket
The GraphQL HTTP端点默认在HTTP POST /graphql。
它还支持Server Sent Events中的
Spring MVC 和 Spring WebFlux 的 HTTP 端点均由一个类型为 0 且带有 @Order 的 RouterFunction Bean 提供。
如果您定义了自己的 RouterFunction Bean,可能需要添加适当的 @Order 注解,以确保它们被正确排序。 |
The GraphQL WebSocket端点默认是关闭的。要启用它,请参阅相关文档。
-
对于Servlet应用程序,在其中添加WebSocketStarters
spring-boot-starter-websocket -
对于WebFlux应用,不需要额外依赖
-
对于两者而言,必须设置
spring.graphql.websocket.path应用属性
Spring GraphQL 提供了一个 Web 拦截 模型。
这对于从 HTTP 请求头中检索信息并将其设置到 GraphQL 上下文中,或者从同一上下文中获取信息并写入响应头非常有用。
使用 Spring Boot,您可以声明一个 WebGraphQlInterceptor Bean,以便将其注册到 Web 传输中。
Spring MVC 和 Spring WebFlux 均支持 CORS(跨域资源共享)请求。 CORS 是 GraphQL 应用程序 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,你可以在组件中注入使用:
-
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<*>) {
然后发送请求: <pre><code>include-code::RSocketGraphQlClientExample[tag=request]</code></pre>
异常处理
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 暴露出来。
您还可以在启用/graphql/schema属性时,在spring.graphql.schema.printer.enabled处以文本格式暴露GraphQL模式。