此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring GraphQL 1.3.3! |
请求执行
ExecutionGraphQlService
是调用 GraphQL Java 执行的主要 Spring 抽象
请求。底层传输(如 HTTP)委托给ExecutionGraphQlService
处理请求。
主要实现DefaultExecutionGraphQlService
配置了GraphQlSource
要访问graphql.GraphQL
实例。
GraphQLSource
GraphQlSource
是一个合约,用于公开graphql.GraphQL
instance 来使用该
包含用于构建该实例的构建器 API。默认构建器可通过GraphQlSource.schemaResourceBuilder()
.
Boot Starter 会创建此构建器的实例并进一步初始化它
要从可配置位置加载 Schema 文件,
公开要应用到的属性GraphQlSource.Builder
,以检测RuntimeWiringConfigurer
beans、用于 GraphQL 指标的插桩 bean、
和DataFetcherExceptionResolver
和SubscriptionExceptionResolver
bean 来解决异常。对于进一步的自定义,您还可以
声明一个GraphQlSourceBuilderCustomizer
bean,例如:
@Configuration(proxyBeanMethods = false)
class GraphQlConfig {
@Bean
public GraphQlSourceBuilderCustomizer sourceBuilderCustomizer() {
return (builder) ->
builder.configureGraphQl(graphQlBuilder ->
graphQlBuilder.executionIdProvider(new CustomExecutionIdProvider()));
}
}
Schema 资源
GraphQlSource.Builder
可以配置一个或多个Resource
实例为
解析并合并在一起。这意味着 schema 文件几乎可以从任何
位置。
默认情况下,Boot Starters会查找带有扩展名的 schema 文件
位置下的 “.graphqls” 或 “.gqls”classpath:graphql/**
,这通常是src/main/resources/graphql
.您还可以使用文件系统位置或任何位置
由 Spring 提供支持Resource
层次结构,包括自定义实现
从远程位置、存储或内存加载架构文件。
用classpath*:graphql/**/ 在多个 Classpath 中查找 schema 文件
位置,例如跨多个模块。 |
Schema 创建
默认情况下,GraphQlSource.Builder
使用 GraphQL JavaSchemaGenerator
要创建graphql.schema.GraphQLSchema
.这适用于典型用途,但如果您需要使用
不同的生成器,例如对于联合,您可以注册一个schemaFactory
回调:
GraphQlSource.Builder builder = ...
builder.schemaResources(..)
.configureRuntimeWiring(..)
.schemaFactory((typeDefinitionRegistry, runtimeWiring) -> {
// create GraphQLSchema
})
GraphQlSource 部分解释了如何使用 Spring Boot 进行配置。
有关 Apollo Federation 的示例,请参见 federation-jvm-spring-example。
RuntimeWiringConfigurer
您可以使用RuntimeWiringConfigurer
要注册:
-
自定义标量类型。
-
违约
TypeResolver
用于接口和联合类型。 -
DataFetcher
对于字段,尽管应用程序通常会使用带注释的控制器,并且 这些被检测并注册为DataFetcher
s byAnnotatedControllerConfigurer
, 这是一个RuntimeWiringConfigurer
.Boot Starter 会自动注册AnnotatedControllerConfigurer
.
GraphQL Java 服务器应用程序仅将 Jackson 用于与数据映射之间的序列化。 客户端输入被解析为 Map。服务器输出将根据字段选择集组装到地图中。 这意味着您不能依赖 Jackson 序列化/反序列化 Comments。 相反,您可以使用自定义标量类型。 |
Boot Starter 检测 bean 类型的RuntimeWiringConfigurer
和
将它们注册到GraphQlSource.Builder
.这意味着在大多数情况下,您将拥有
类似于 this 的配置:
@Configuration
public class GraphQlConfig {
@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer(BookRepository repository) {
GraphQLScalarType scalarType = ... ;
SchemaDirectiveWiring directiveWiring = ... ;
DataFetcher dataFetcher = QuerydslDataFetcher.builder(repository).single();
return wiringBuilder -> wiringBuilder
.scalar(scalarType)
.directiveWiring(directiveWiring)
.type("Query", builder -> builder.dataFetcher("book", dataFetcher));
}
}
如果您需要添加WiringFactory
,例如,进行注册时要考虑到
schema definitions 中,实现替代configure
方法,该方法同时接受RuntimeWiring.Builder
和一个输出List<WiringFactory>
.这允许您添加任何
然后按顺序调用的工厂数。
TypeResolver
GraphQlSource.Builder
寄存 器ClassNameTypeResolver
作为默认值TypeResolver
用于尚未进行此类注册的 GraphQL 接口和联合
通过RuntimeWiringConfigurer
.目的
一个TypeResolver
在 GraphQL 中,Java 用于确定值的 GraphQL 对象类型
从DataFetcher
对于 GraphQL Interface (图形QL 接口) 或 Union (联合) 字段。
ClassNameTypeResolver
尝试将值的简单类名与 GraphQL 匹配
Object 类型,如果不成功,它还会导航其超类型,包括
基类和接口,寻找匹配项。ClassNameTypeResolver
提供了一个
选项配置名称提取函数以及Class
更改为 GraphQL 对象类型
名称映射应该有助于涵盖更多极端情况:
GraphQlSource.Builder builder = ...
ClassNameTypeResolver classNameTypeResolver = new ClassNameTypeResolver();
classNameTypeResolver.setClassNameExtractor((klass) -> {
// Implement Custom ClassName Extractor here
});
builder.defaultTypeResolver(classNameTypeResolver);
GraphQlSource 部分解释了如何使用 Spring Boot 进行配置。
指令
GraphQL 语言支持“描述替代运行时执行和 GraphQL 文档中的类型验证行为”。指令类似于 Java,但在 GraphQL 文档中的类型、字段、片段和作上声明。
GraphQL Java 提供了SchemaDirectiveWiring
Contract 帮助应用程序检测
和 handle 指令。有关更多详细信息,请参阅
GraphQL Java 文档。
在 Spring GraphQL 中,你可以注册一个SchemaDirectiveWiring
通过RuntimeWiringConfigurer
.Boot Starter 检测到
这样的 bean,所以你可能会有这样的东西:
@Configuration
public class GraphQlConfig {
@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer() {
return builder -> builder.directiveWiring(new MySchemaDirectiveWiring());
}
}
有关指令支持的示例,请查看 Graphql Java 库的扩展验证。 |
ExecutionStrategy
一ExecutionStrategy
在 GraphQL 中,Java 驱动请求的字段的获取。
要创建ExecutionStrategy
,您需要提供DataFetcherExceptionHandler
.
默认情况下,Spring for GraphQL 会创建异常处理程序以使用,如 异常 中所述,并将其设置在GraphQL.Builder
.然后,GraphQL Java 使用它来创建AsyncExecutionStrategy
实例。
如果您需要创建自定义ExecutionStrategy
中,您可以检测到DataFetcherExceptionResolver
s 并以相同的方式创建异常处理程序,并使用
it 创建自定义ExecutionStrategy
.例如,在 Spring Boot 应用程序中:
@Bean
GraphQlSourceBuilderCustomizer sourceBuilderCustomizer(
ObjectProvider<DataFetcherExceptionResolver> resolvers) {
DataFetcherExceptionHandler exceptionHandler =
DataFetcherExceptionResolver.createExceptionHandler(resolvers.stream().toList());
AsyncExecutionStrategy strategy = new CustomAsyncExecutionStrategy(exceptionHandler);
return sourceBuilder -> sourceBuilder.configureGraphQl(builder ->
builder.queryExecutionStrategy(strategy).mutationExecutionStrategy(strategy));
}
架构转换
您可以注册一个graphql.schema.GraphQLTypeVisitor
通过builder.schemaResources(..).typeVisitorsToTransformSchema(..)
如果要遍历
并在创建架构后对其进行转换,然后对架构进行更改。注意事项
这通常比 Schema Traversal 更昂贵
首选遍历而不是转换,除非您需要进行架构更改。
架构遍历
您可以注册一个graphql.schema.GraphQLTypeVisitor
通过builder.schemaResources(..).typeVisitors(..)
如果要在
它已创建,并且可能会将更改应用于GraphQLCodeRegistry
.请记住,
但是,此类访客无法更改架构。如果需要更改架构,请参阅 架构转换。
Schema 映射检查
如果查询、更改或订阅作没有DataFetcher
,则不会
返回任何数据,并且不会执行任何有用的作。同样,返回的架构类型的字段
通过一个作,该作既未通过DataFetcher
registration,也不是默认的PropertyDataFetcher
,它会查找
匹配的 Java 对象属性,将始终为null
.
GraphQL Java 不执行检查以确保覆盖每个架构字段,并且
可能会导致可能无法发现的差距,具体取决于测试覆盖率。在运行时
你可能会得到一个 “静音”null
,或者如果字段不可为空,则为 error。作为较低级别
库,GraphQL Java 根本不了解DataFetcher
implementations 和
它们的返回类型,因此无法将架构类型结构与 Java 对象进行比较
结构。
Spring for GraphQL 定义了SelfDescribingDataFetcher
接口以允许DataFetcher
以公开返回类型信息。全部 SpringDataFetcher
实现
实现此接口。这包括用于 Annotated Controllers 的那些,以及用于 Querydsl 和 Query by Example Spring Data 存储库的那些。对于带注释的
controllers 的 Controllers 中,返回类型派生自@SchemaMapping
方法。
在启动时,Spring for GraphQL 可以检查架构字段、DataFetcher
注册
以及从DataFetcher
要检查的 implementations
如果所有 schema 字段都被显式注册的DataFetcher
或
匹配的 Java 对象属性。检查还会执行反向检查,寻找DataFetcher
针对不存在的架构字段的注册。
要启用架构映射检查,请执行以下作:
GraphQlSource.Builder builder = ...
builder.schemaResources(..)
.inspectSchemaMappings(report -> {
logger.debug(report);
})
下面是一个示例报告:
GraphQL schema inspection: Unmapped fields: {Book=[title], Author[firstName, lastName]} (1) Unmapped registrations: {Book.reviews=BookController#reviews[1 args]} (2) Skipped types: [BookOrAuthor] (3)
1 | 未映射的架构字段及其源类型的列表 |
2 | 列表DataFetcher 在不存在的字段上注册 |
3 | 跳过的架构类型列表,如下所述 |
架构字段检查可以执行的作是有限的,尤其是当存在
Java 类型信息不足。如果带注释的控制器方法是
声明返回java.lang.Object
,或者如果返回类型具有未指定的泛型
参数,例如List<?>
,或者如果DataFetcher
不实现SelfDescribingDataFetcher
返回类型甚至未知。在这种情况下,
Java 对象类型结构仍然未知,并且架构类型在
生成的报告。对于每个跳过的类型,都会记录一条 DEBUG 消息以说明原因
它被跳过了。
架构联合类型总是被跳过,因为控制器方法无法 在 Java 中声明这样的返回类型,Java 类型结构是未知的。
架构接口类型仅支持直接声明的字段,这些字段是
与由SelfDescribingDataFetcher
.
不检查具体实现上的其他字段。这有待改进
在将来的版本中,还要检查 schemainterface
implementation types 和 try
在声明的 Java 返回类型的子类型之间查找匹配项。
Operation Caching
GraphQL Java 必须在执行作之前对其进行解析和验证。这可能会影响
性能显着。为避免需要重新分析和验证,应用程序可以
配置PreparsedDocumentProvider
缓存和重用 Document 实例。GraphQL Java 文档提供了有关以下内容的更多详细信息
查询缓存PreparsedDocumentProvider
.
在 Spring GraphQL 中,你可以注册一个PreparsedDocumentProvider
通过GraphQlSource.Builder#configureGraphQl
:
.
// Typically, accessed through Spring Boot's GraphQlSourceBuilderCustomizer
GraphQlSource.Builder builder = ...
// Create provider
PreparsedDocumentProvider provider =
new ApolloPersistedQuerySupport(new InMemoryPersistedQueryCache(Collections.emptyMap()));
builder.schemaResources(..)
.configureRuntimeWiring(..)
.configureGraphQl(graphQLBuilder -> graphQLBuilder.preparsedDocumentProvider(provider))
GraphQlSource 部分解释了如何使用 Spring Boot 进行配置。
螺纹模型
大多数 GraphQL 请求都受益于获取嵌套字段的并发执行。这是
为什么当今大多数应用程序都依赖于 GraphQL Java 的AsyncExecutionStrategy
,它允许
要返回的数据获取器CompletionStage
以及并发执行而不是串行执行。
Java 21 和虚拟线程增加了一个重要的功能,可以有效地使用更多线程,但是 仍然需要并发执行,而不是串行执行,以便请求 执行以更快地完成。
Spring for GraphQL 支持:
-
响应式数据获取器,它们是 适应于
CompletionStage
如预期AsyncExecutionStrategy
. -
CompletionStage
作为返回值。 -
Controller 方法,即 Kotlin 协程方法。
-
@SchemaMapping 和 @BatchMapping 方法可以返回
Callable
提交到Executor
例如 Spring FrameworkVirtualThreadTaskExecutor
.要启用此功能,您必须配置Executor
上AnnotatedControllerConfigurer
.
Spring for GraphQL 在 Spring MVC 或 WebFlux 上运行作为传输。Spring MVC
使用异步请求执行,除非生成的CompletableFuture
已完成
在 GraphQL Java 引擎返回后立即返回,如果
request 足够简单,不需要异步数据获取。
反应性的DataFetcher
默认的GraphQlSource
builder 启用对DataFetcher
返回Mono
或Flux
这会将它们调整为CompletableFuture
哪里Flux
值被聚合
并转换为 List,除非请求是 GraphQL 订阅请求,
在这种情况下,返回值仍然是 Reactive StreamsPublisher
用于流媒体
GraphQL 响应。
反应式DataFetcher
可以依赖对从
传输层,例如从 WebFlux 请求处理,请参阅 WebFlux 上下文。
上下文传播
Spring for GraphQL 支持通过 GraphQL Java 透明地从 HTTP 传输传播上下文,并传递到DataFetcher
以及它调用的其他组件。这包括ThreadLocal
上下文
从 Spring MVC 请求处理线程和 ReactorContext
来自 WebFlux
处理管道。
WebMvc 网络
一个DataFetcher
和 GraphQL Java 调用的其他组件可能并不总是在
与 Spring MVC 处理程序相同的线程,例如,如果WebGraphQlInterceptor
或DataFetcher
切换到
不同的线程。
Spring for GraphQL 支持传播ThreadLocal
来自 Servlet 容器的值
thread 设置为线程 aDataFetcher
和其他组件,以
执行时间。为此,应用程序需要实现io.micrometer.context.ThreadLocalAccessor
对于ThreadLocal
感兴趣的值:
public class RequestAttributesAccessor implements ThreadLocalAccessor<RequestAttributes> {
@Override
public Object key() {
return RequestAttributesAccessor.class.getName();
}
@Override
public RequestAttributes getValue() {
return RequestContextHolder.getRequestAttributes();
}
@Override
public void setValue(RequestAttributes attributes) {
RequestContextHolder.setRequestAttributes(attributes);
}
@Override
public void reset() {
RequestContextHolder.resetRequestAttributes();
}
}
您可以注册一个ThreadLocalAccessor
在启动时使用全局ContextRegistry
实例,可通过io.micrometer.context.ContextRegistry#getInstance()
.您也可以注册它
自动通过java.util.ServiceLoader
机制。
WebFlux的
一个反应性的DataFetcher
可以依赖对 Reactor 上下文的访问,该
源自 WebFlux 请求处理链。这包括 Reactor 上下文
由 WebGraphQlInterceptor 组件添加。
异常
在 GraphQL Java 中,DataFetcherExceptionHandler
决定如何表示异常
在响应的 “errors” 部分中获取数据。应用程序可以注册
仅限单个处理程序。
Spring for GraphQL 注册了一个DataFetcherExceptionHandler
提供默认
处理并启用DataFetcherExceptionResolver
合同。应用程序可以
通过以下方式注册任意数量的解析器GraphQLSource
builder 中,这些位于
order 中,直到他们解决Exception
更改为List<graphql.GraphQLError>
.
Spring Boot Starters检测这种类型的 bean。
DataFetcherExceptionResolverAdapter
是具有受保护方法的便捷基类resolveToSingleError
和resolveToMultipleErrors
.
带注释的控制器编程模型允许使用
具有灵活方法签名的带注释的异常处理程序方法,请参阅@GraphQlExceptionHandler
了解详情。
一个GraphQLError
可以根据 GraphQL Java 分配给类别graphql.ErrorClassification
或 Spring GraphQLErrorType
,其中定义了以下内容:
-
BAD_REQUEST
-
UNAUTHORIZED
-
FORBIDDEN
-
NOT_FOUND
-
INTERNAL_ERROR
如果异常仍未解决,则默认情况下,它被归类为INTERNAL_ERROR
替换为包含类别名称和executionId
从DataFetchingEnvironment
.该消息故意不透明以避免泄漏
实现细节。应用程序可以使用DataFetcherExceptionResolver
自定义
错误详细信息。
未解决的异常将记录在 ERROR 级别,并且executionId
关联
发送到客户端的错误。已解决的异常记录在 DEBUG 级别。
请求例外
GraphQL Java 引擎在解析请求时可能会遇到验证或其他错误
这反过来又会阻止请求执行。在这种情况下,响应包含
“data” 键替换为null
以及一个或多个请求级 “错误” 是全局的,即 not
具有字段路径。
DataFetcherExceptionResolver
无法处理此类全局错误,因为它们是引发的
在执行开始之前和任何DataFetcher
被调用。应用程序可以使用
传输级拦截器来检查和转换ExecutionResult
.
请参阅下面的示例WebGraphQlInterceptor
.
分页
GraphQL 游标连接规范定义了一种导航大型结果集的方法,方法是在以下时间返回项目子集 每个项目都与一个游标配对,客户端可以使用该游标在 或 在被引用项之后。
该规范将模式称为 “连接”。名称以
on Connection 是表示分页结果集的 Connection Type。都~Connection
类型包含一个 “edges” 字段,其中~Edge
type 将实际项与游标配对,因为
以及带有布尔标志的 “pageInfo” 字段,用于指示是否有更多项目转发
和向后。
连接类型
Connection
必须为每个需要分页的类型创建类型定义,添加
样板和干扰添加到架构中。Spring for GraphQL 提供ConnectionTypeDefinitionConfigurer
在启动时添加这些类型(如果尚未添加)
存在于解析的架构文件中。这意味着在 schema 中,您只需要:
Query {
books(first:Int, after:String, last:Int, before:String): BookConnection
}
type Book {
id: ID!
title: String!
}
请注意 spec 定义的前向分页参数first
和after
客户端可以使用
请求给定游标之后的前 N 项,而last
和before
是落后的
pagination 参数来请求给定游标之前的最后 N 项。
接下来,配置ConnectionTypeDefinitionConfigurer
如下:
GraphQlSource.schemaResourceBuilder()
.schemaResources(..)
.typeDefinitionConfigurer(new ConnectionTypeDefinitionConfigurer)
以下类型定义将透明地添加到 schema 中:
type BookConnection {
edges: [BookEdge]!
pageInfo: PageInfo!
}
type BookEdge {
node: Book!
cursor: String!
}
type PageInfo {
hasPreviousPage: Boolean!
hasNextPage: Boolean!
startCursor: String
endCursor: String
}
Boot Starter 寄存器ConnectionTypeDefinitionConfigurer
默认情况下。
ConnectionAdapter
一旦 Connection Types 在 schema 中可用,您还需要
等效的 Java 类型。GraphQL Java 提供了这些 API,包括通用的Connection
和Edge
以及PageInfo
.
一种选择是填充Connection
并从控制器方法返回它,或者DataFetcher
.但是,这需要样板代码来创建Connection
,
创建游标,将每个项目包装为Edge
,并创建PageInfo
.
此外,您可能已经有一个底层的分页机制,例如在使用
Spring Data 存储库。
Spring for GraphQL 定义了ConnectionAdapter
contract 来调整 items 的容器
自Connection
.适配器通过DataFetcher
decorator 的
通过ConnectionFieldTypeVisitor
.您可以按如下方式对其进行配置:
ConnectionAdapter adapter = ... ;
GraphQLTypeVisitor visitor = ConnectionFieldTypeVisitor.create(List.of(adapter)) (1)
GraphQlSource.schemaResourceBuilder()
.schemaResources(..)
.typeDefinitionConfigurer(..)
.typeVisitors(List.of(visitor)) (2)
1 | 创建具有一个或多个ConnectionAdapter s. |
2 | 抵制类型的访客。 |
有内置的 ConnectionAdapter
s 代表 Spring Data 的Window
和Slice
.您还可以创建自己的自定义适配器。ConnectionAdapter
实现依赖于CursorStrategy
自
为返回的项目创建游标。相同的策略也用于支持Subrange
controller 方法参数,其中包含
pagination input 的 API 中。
CursorStrategy
CursorStrategy
是一个合约,用于对引用
项在大型结果集中的位置。游标可以基于索引或
在键集上。
一个ConnectionAdapter
使用它来对返回项目的游标进行编码。带注释的 Controllers 方法、Querydsl 存储库和 Query by Example 存储库使用它来解码分页请求中的游标,并创建一个Subrange
.
CursorEncoder
是一个相关的合约,它进一步编码和解码 String 游标为
使它们对客户不透明。EncodingCursorStrategy
结合CursorStrategy
替换为CursorEncoder
.您可以使用Base64CursorEncoder
,NoOpEncoder
或创建自己的。
有一个内置的 CursorStrategy
对于 Spring DataScrollPosition
.Boot Starter 注册一个CursorStrategy<ScrollPosition>
跟Base64Encoder
当 Spring Data 存在时。
排序
在 GraphQL 请求中没有提供排序信息的标准方法。然而 分页取决于稳定的排序顺序。您可以使用默认订单,或者其他方式 公开输入类型并从 GraphQL 参数中提取排序详细信息。
内置了对 Spring Data 的Sort
作为控制器
method 参数。要使其正常工作,您需要有一个SortStrategy
豆。
批量加载
给定一个Book
及其Author
,我们可以创建一个DataFetcher
一本书和另一本书
对于它的作者。这允许选择有作者或无作者的书籍,但这意味着书籍
和 authors 不会一起加载,这在查询多个
books 作为每本书的作者是单独加载的。这称为 N+1 选择
问题。
DataLoader
GraphQL Java 提供了一个DataLoader
用于批量加载相关实体的机制。
您可以在 GraphQL Java 文档中找到完整的详细信息。下面是一个
工作原理摘要:
-
注册
DataLoader
在DataLoaderRegistry
,它可以加载给定唯一键的实体。 -
DataFetcher
的 can accessDataLoader
的 ID 值,并使用它们按 ID 加载实体。 -
一个
DataLoader
通过返回 future 来延迟加载,以便可以批量完成。 -
DataLoader
维护加载实体的每个请求缓存,该缓存可以进一步 提高效率。
BatchLoaderRegistry
GraphQL Java 中的完整批处理加载机制需要实现以下之一
几个BatchLoader
接口,然后将它们包装并注册为DataLoader
s
,名称位于DataLoaderRegistry
.
Spring GraphQL 中的 API 略有不同。对于注册,只有一个
中央BatchLoaderRegistry
公开工厂方法和构建器以创建和
注册任意数量的批量加载函数:
@Configuration
public class MyConfig {
public MyConfig(BatchLoaderRegistry registry) {
registry.forTypePair(Long.class, Author.class).registerMappedBatchLoader((authorIds, env) -> {
// return Mono<Map<Long, Author>
});
// more registrations ...
}
}
Boot Starter 声明了一个BatchLoaderRegistry
你可以注入的 bean
您的配置,如上所示,或按顺序放入任何组件(如控制器)
注册批量加载函数。反过来,BatchLoaderRegistry
被注入DefaultExecutionGraphQlService
确保DataLoader
每个请求的注册数。
默认情况下,DataLoader
name 基于目标实体的类名。
这允许@SchemaMapping
方法声明具有泛型类型的 DataLoader 参数,以及
无需指定名称。但是,可以通过BatchLoaderRegistry
builder(如有必要)以及其他DataLoaderOptions
.
配置默认DataLoaderOptions
全局,以用作任何
registration,您可以覆盖 Boot 的BatchLoaderRegistry
bean 并使用构造函数
为DefaultBatchLoaderRegistry
接受Supplier<DataLoaderOptions>
.
在许多情况下,在加载相关实体时,您可以使用 @BatchMapping 控制器方法,这是一种快捷方式
for 并替换需要使用BatchLoaderRegistry
和DataLoader
径直。
BatchLoaderRegistry
还提供其他重要的好处。它支持访问
一样GraphQLContext
from batch loading functions 和 from@BatchMapping
方法
以及确保对它们的上下文传播。这就是预期应用的原因
以使用它。可以执行你自己的DataLoader
registrations 直接注册,但
此类注册将放弃上述好处。
测试 Batch Loading
首先BatchLoaderRegistry
在DataLoaderRegistry
:
BatchLoaderRegistry batchLoaderRegistry = new DefaultBatchLoaderRegistry();
// perform registrations...
DataLoaderRegistry dataLoaderRegistry = DataLoaderRegistry.newRegistry().build();
batchLoaderRegistry.registerDataLoaders(dataLoaderRegistry, graphQLContext);
现在您可以访问和测试个人DataLoader
如下所示:
DataLoader<Long, Book> loader = dataLoaderRegistry.getDataLoader(Book.class.getName());
loader.load(1L);
loader.loadMany(Arrays.asList(2L, 3L));
List<Book> books = loader.dispatchAndJoin(); // actual loading
assertThat(books).hasSize(3);
assertThat(books.get(0).getName()).isEqualTo("...");
// ...