Spring GraphQL 为构建在GraphQL Java上的 Spring 应用程序提供支持。这是两个团队之间的联合协作。我们的共同理念是少固执己见,更专注于全面和广泛的支持。
Spring GraphQL 是GraphQL Java 团队的GraphQL Java Spring项目的继承者。它旨在成为所有 Spring、GraphQL 应用程序的基础。
网络传输
Spring GraphQL 支持通过 HTTP 和 WebSocket 的 GraphQL 请求。
HTTP
GraphQlHttpHandler
通过 HTTP 请求处理 GraphQL,并委托给 Web 拦截链来执行请求。有两种变体,一种用于 Spring MVC,一种用于 Spring WebFlux。两者都异步处理请求并具有等效的功能,但分别依赖阻塞和非阻塞 I/O 来编写 HTTP 响应。
请求必须使用 HTTP POST 和 GraphQL 请求详细信息作为 JSON 包含在请求正文中,如提议的GraphQL over HTTP 规范中所定义 。成功解码 JSON 正文后,HTTP 响应状态始终为 200(OK),并且 GraphQL 请求执行中的任何错误都会出现在 GraphQL 响应的“错误”部分。
GraphQlHttpHandler
可以通过声明一个RouterFunction
bean 并使用RouterFunctions
来自 Spring MVC 或 WebFlux 的来创建路由来作为 HTTP 端点公开。Boot starter 执行此操作。
Spring GraphQL 存储库包含一个 Spring MVC HTTP 示例应用程序。
网络套接字
GraphQlWebSocketHandler
基于graphql-ws库中定义 的协议通过 WebSocket 请求处理 GraphQL 。在 WebSocket 上使用 GraphQL 的主要原因是订阅,它允许发送 GraphQL 响应流,但它也可以用于具有单个响应的常规查询。处理程序将每个请求委托给Web 拦截链以进一步执行请求。
有两种变体GraphQlWebSocketHandler
,一种用于 Spring MVC,一种用于 Spring WebFlux。两者都异步处理请求并具有等效的功能。WebFlux 处理程序还使用非阻塞 I/O 和背压来流式传输消息,这很有效,因为在 GraphQL Java 中订阅响应是 Reactive Streams Publisher
。
该graphql-ws
项目列出了许多供客户使用的 配方。
GraphQlWebSocketHandler
可以通过声明SimpleUrlHandlerMapping
bean 并使用它将处理程序映射到 URL 路径来公开为 WebSocket 端点 。Boot starter 具有启用此功能的选项,有关详细信息或检查 或例如配置,请参阅Web 端点。GraphQlWebMvcAutoConfigurationGraphQlWebFluxAutoConfiguration
Spring GraphQL 存储库包含一个 WebFlux WebSocket 示例应用程序。
网页拦截
HTTP和WebSocket传输处理程序委托给一个通用的 Web 拦截链来执行请求。该链由一系列 WebInterceptor
组件组成,后跟一个GraphQlService
调用 GraphQL Java 引擎的 。
WebInterceptor
作为在 Spring MVC 和 WebFlux 应用程序中使用的通用契约。使用它来拦截请求、检查 HTTP 请求标头或注册以下内容的转换graphql.ExecutionInput
:
class MyInterceptor implements WebInterceptor {
@Override
public Mono<WebOutput> intercept(WebInput webInput, WebGraphQlHandler next) {
webInput.configureExecutionInput((executionInput, builder) -> {
Map<String, Object> map = ... ;
return builder.extensions(map).build();
});
return next.handle(webInput);
}
}
使用WebInterceptor
也拦截响应,增加HTTP响应头,或转换graphql.ExecutionResult
:
class MyInterceptor implements WebInterceptor {
@Override
public Mono<WebOutput> intercept(WebInput webInput, WebGraphQlHandler next) {
return next.handle(webInput)
.map(webOutput -> {
Object data = webOutput.getData();
Object updatedData = ... ;
return webOutput.transform(builder -> builder.data(updatedData));
});
}
}
WebGraphQlHandler
提供了一个builder来初始化Web拦截链。构建链后,您可以使用结果WebGraphQlHandler
来初始化 HTTP 或 WebSocket 传输处理程序。Boot starter 配置了所有这些,有关详细信息,请参阅Web Endpoints,或检查GraphQlWebMvcAutoConfiguration
或GraphQlWebFluxAutoConfiguration
例如 config。
查询执行
GraphQlService
是调用 GraphQL Java 来执行请求的主要 Spring GraphQL 抽象。底层传输,例如Web 传输,委托GraphQlService
来处理请求。
主要实现ExecutionGraphQlService
是围绕 的调用的薄外观graphql.GraphQL
。它配置了一个GraphQlSource
用于访问graphql.GraphQL
实例。
GraphQLSource
GraphQlSource
是核心 Spring GraphQL 抽象,用于访问graphql.GraphQL
用于请求执行的 实例。它提供了一个构建器 API 来初始化 GraphQL Java 并构建一个GraphQlSource
.
GraphQlSource
可通过 访问的默认构建器GraphQlSource.builder()
支持ReactiveDataFetcher
、Context Propagation和 Exception Resolution。
反应式 DataFetcher
默认GraphQlSource
构建器启用对 aDataFetcher
返回Mono
或 的支持Flux
。无论返回类型适合在一个CompletableFuture
与Flux
聚集,变成了一个列表值,除非请求是GraphQL订阅请求,在这种情况下返回值保持在无流Publisher
的流GraphQL响应。
反应式DataFetcher
可以依赖对从传输层传播的 Reactor 上下文的访问,例如来自 WebFlux 请求处理,请参阅 WebFlux 上下文。
上下文传播
Spring GraphQL 支持从Web 传输、通过 GraphQL 引擎以及DataFetcher
它调用的其他组件透明地传播上下文。这包括ThreadLocal
来自 Spring MVC 请求处理线程的上下文和Context
来自 WebFlux 处理管道的Reactor 。
网管
DataFetcher
GraphQL Java 调用的A和其他组件可能并不总是在与 Spring MVC 处理程序相同的线程上执行,例如,如果异步 WebInterceptor
或DataFetcher
切换到不同的线程。
Spring GraphQL 支持将ThreadLocal
值从 Servlet 容器线程传播到线程 aDataFetcher
以及由 GraphQL 引擎调用的其他组件执行。为此,应用程序需要创建一个ThreadLocalAccessor
来提取 ThreadLocal
感兴趣的值:
public class RequestAttributesAccessor implements ThreadLocalAccessor {
private static final String KEY = RequestAttributesAccessor.class.getName();
@Override
public void extractValues(Map<String, Object> container) {
container.put(KEY, RequestContextHolder.getRequestAttributes());
}
@Override
public void restoreValues(Map<String, Object> values) {
if (values.containsKey(KEY)) {
RequestContextHolder.setRequestAttributes((RequestAttributes) values.get(KEY));
}
}
@Override
public void resetValues(Map<String, Object> values) {
RequestContextHolder.resetRequestAttributes();
}
}
AThreadLocalAccessor
可以在WebGraphHandler构建器中注册。Boot starter 检测这种类型的 bean 并自动为 Spring MVC 应用程序注册它们,请参阅Web Endpoints。
网络流量
一个反应DataFetcher
可以依靠获取反应堆背景下,从WebFlux源自请求处理链。这包括由WebInterceptor组件添加的 Reactor 上下文。
异常解决
GraphQL Java 应用程序可以注册 aDataFetcherExceptionHandler
来决定如何在 GraphQL 响应的“错误”部分中表示来自数据层的异常。
Spring GraphQL 有一个内置的DataFetcherExceptionHandler
,配置为供GraphQLSource
构建器使用。它使应用程序能够注册一个或多个DataFetcherExceptionResolver
按顺序调用的Spring组件,直到将 解析Exception
为graphql.GraphQLError
对象列表。
DataFetcherExceptionResolver
是一个异步合约。对于大多数实现,这将是足够的扩展DataFetcherExceptionResolverAdapter
和覆盖其一个resolveToSingleError
或resolveToMultipleErrors
方法是解决异常同步。
AGraphQLError
可以分配一个graphql.ErrorClassification
. Spring GraphQL 定义了一个ErrorType
具有常见错误分类类别的枚举:
BAD_REQUEST
UNAUTHORIZED
FORBIDDEN
NOT_FOUND
INTERNAL_ERROR
应用程序可以使用它来分类错误。如果错误仍未解决,则默认情况下将其标记为INTERNAL_ERROR
。
未完待续......