Spring for GraphQL

如果您想构建 GraphQL 应用程序,您可以利用 Spring Boot 对 {url-spring-graphql-site}[Spring for GraphQL] 的自动配置。Spring for GraphQL 项目基于 GraphQL Java。至少需要 spring-boot-starter-graphql 启动器。由于 GraphQL 与传输无关,因此还需要在应用程序中添加一个或多个启动器,以通过 Web 公开您的 GraphQL API:

Starter Transport Implementation

spring-boot-starter-web

HTTP

Spring MVC

spring-boot-starter-websocket

WebSocket

WebSocket for Servlet apps

spring-boot-starter-webflux

HTTP, WebSocket

Spring WebFlux

spring-boot-starter-rsocket

TCP, WebSocket

Reactor Netty 上的 Spring WebFlux

GraphQL Schema

Spring GraphQL 应用程序在启动时需要定义一个架构。默认情况下,可以在 src/main/resources/graphql/** 下编写 “.graphqls” 或 “.gqls” 架构文件,Spring Boot 将自动提取它们。您可以使用 configprop:spring.graphql.schema.locations[] 自定义位置,并使用 configprop:spring.graphql.schema.file-extensions[] 自定义文件扩展名。

如果您希望 Spring Boot 检测您在应用程序的所有模块和依赖项中的给定位置的架构文件,则可以将 configprop:spring.graphql.schema.locations[] 设置为 "classpath*:graphql/*/" (note the classpath: 前缀)。

在以下部分中,我们将考虑此示例 GraphQL 架构,定义两个类型和两个查询:

Unresolved include directive in modules/ROOT/pages/web/spring-graphql.adoc - include::ROOT:example$resources/graphql/schema.graphqls[]

默认情况下, field introspection 将被允许在架构上,因为 GraphiQL 等工具需要它。如果您不希望公开关于架构的信息,则可以通过将 configprop:spring.graphql.schema.introspection.enabled[] 设置为 false 来禁用内省。

GraphQL RuntimeWiring

GraphQL Java RuntimeWiring.Builder 可用于注册自定义标量类型、指令、类型解析器、DataFetcher,等等。可在你的 Spring 配置中声明 RuntimeWiringConfigurer bean,以获取对 RuntimeWiring.Builder 的访问权限。Spring Boot 将检测此类 bean 并将它们添加到 {url-spring-graphql-docs}/#execution-graphqlsource[GraphQlSource 生成器]。

然而,通常,应用程序不会直接实现 DataFetcher,而是创建 {url-spring-graphql-docs}/#controllers[带注释的控制器]。Spring Boot 将自动检测有带注释处理程序方法的 @Controller 类,并将这些注册为 DataFetcher`s. Here’s a sample implementation for our greeting query with a `@Controller 类:

Querydsl and QueryByExample Repositories Support

Spring Data 同时提供对 Querydsl 和 QueryByExample 存储库的支持。Spring GraphQL 可以将 {url-spring-graphql-docs}/#data[Querydsl 和 QueryByExample 存储库配置成 DataFetcher]。

@GraphQlRepository 注释并扩展下列类之一的 Spring Data 存储库:

  • QuerydslPredicateExecutor

  • ReactiveQuerydslPredicateExecutor

  • QueryByExampleExecutor

  • ReactiveQueryByExampleExecutor

将被 Spring Boot 检测,并被视为匹配顶级查询的 DataFetcher 候选。

Transports

HTTP and WebSocket

默认情况下,GraphQL HTTP 端点位于 HTTP POST /graphql。它还支持仅用于订阅的 Server Sent Events 的 "text/event-stream" 媒体类型。可使用 configprop:spring.graphql.path[] 自定义路径。

适用于 Spring MVC 和 Spring WebFlux 的 HTTP 端点由具有 RouterFunction@Order0 bean 提供。如果你定义了自己的 RouterFunction bean,你可能想要添加适当的 @Order 注释,以确保它们按正确的顺序进行排序。

默认情况下,GraphQL WebSocket 端点已关闭。若要启用它:

  • 对于 Servlet 应用程序,添加 WebSocket 启动器 spring-boot-starter-websocket

  • 对于 WebFlux 应用程序,不需要其他依赖关系

  • 对于这两者,必须设置 configprop:spring.graphql.websocket.path[] 应用程序属性

Spring GraphQL 提供了 {url-spring-graphql-docs}/#web-interception[Web 拦截] 模型。此功能非常适用于从 HTTP 请求头中检索信息并将其设置在 GraphQL 上下文中,或者从同一上下文获取信息并将其写入响应头。使用 Spring Boot,你可以声明一个 WebInterceptor bean,以将该 bean 注册到 Web 传输中。

{url-spring-framework-docs}/web/webmvc-cors.html[Spring MVC] 和 {url-spring-framework-docs}/web/webflux-cors.html[Spring WebFlux] 支持 CORS(跨域资源共享)请求。CORS 是通过不同域使用浏览器访问 GraphQL 应用程序时至关重要的 web 配置部分。

Spring Boot 支持 spring.graphql.cors.* 命名空间下的许多配置属性;以下是简短的配置示例:

spring:
  graphql:
    cors:
      allowed-origins: "https://example.org"
      allowed-methods: GET,POST
      max-age: 1800s

RSocket

RSocket 也可以作为传输,位于 WebSocket 或 TCP 之上。一旦设置 RSocket server is configured,我们就可以使用 configprop:spring.graphql.rsocket.mapping[] 在特定路由上配置 GraphQL 处理程序。例如,将该映射配置为 "graphql" 意味着我们可以在用 RSocketGraphQlClient 发送请求时将其用作路由。

Spring Boot 会自动配置一个你可以注入到你的组件中的 RSocketGraphQlClient.Builder<?> bean:

然后发送一个请求:include-code::RSocketGraphQlClientExample[tag=request]

Exception Handling

Spring GraphQL 允许应用程序注册一个或多个 Spring DataFetcherExceptionResolver`组件,这些组件将按顺序调用。异常必须解析为 `graphql.GraphQLError`对象列表,请参阅 {url-spring-graphql-docs}/#execution-exceptions[Spring GraphQL 异常处理文档]。Spring Boot 将自动检测 `DataFetcherExceptionResolver`bean 并将其注册到 `GraphQlSource.Builder

GraphiQL and Schema printer

Spring GraphQL 为开发人员在消费或开发 GraphQL API 时提供了基础设施。

Spring GraphQL 随附一个默认的 GraphiQL页面,默认情况下在 "/graphiql"`中公开。该页面默认情况下处于禁用状态,可以使用 configprop:spring.graphql.graphiql.enabled[] 属性将其打开。公开此类页面的许多应用程序将更喜欢自定义构建。默认实现对于开发非常有用,这就是为什么它在开发过程中使用 `spring-boot-devtools自动公开的原因。

当 configprop:spring.graphql.schema.printer.enabled[] 属性已启用时,您还可以在 `/graphql/schema`中以文本格式公开 GraphQL 模式。