对于最新稳定版本,请使用 Spring GraphQL 2.0.0spring-doc.cadn.net.cn

数据集成

Spring for GraphQL 允许您利用现有的 Spring 技术,遵循常见的编程模型,通过 GraphQL 暴露底层数据源。spring-doc.cadn.net.cn

本节讨论了 Spring Data 的一个集成层,该层提供了一种简单的方式来将 Querydsl 或 Query by Example(示例查询)仓库适配到数据费彻,包括自动检测选项和标记仓库的GraphQL查询注册 跟@GraphQlRepository.spring-doc.cadn.net.cn

Querydsl

Spring for GraphQL 支持使用 Querydsl 通过Spring Data Querydsl 扩展获取数据。Querydsl 提供了一种灵活但类型安全的表达方法,通过使用注释处理器生成元模型。spring-doc.cadn.net.cn

例如,声明一个仓库为QuerydslPredicateExecutor:spring-doc.cadn.net.cn

public interface AccountRepository extends Repository<Account, Long>,
			QuerydslPredicateExecutor<Account> {
}

然后用它来创建一个数据费彻:spring-doc.cadn.net.cn

// For single result queries
DataFetcher<Account> dataFetcher =
		QuerydslDataFetcher.builder(repository).single();

// For multi-result queries
DataFetcher<Iterable<Account>> dataFetcher =
		QuerydslDataFetcher.builder(repository).many();

// For paginated queries
DataFetcher<Iterable<Account>> dataFetcher =
		QuerydslDataFetcher.builder(repository).scrollable();

你现在可以注册上述内容数据费彻通过一个RuntimeWiringConfigurer.spring-doc.cadn.net.cn

数据费彻构建一个 Querydsl谓语并利用它来获取数据。Spring Data 支持QuerydslPredicateExecutor适用于JPA、MongoDB、Neo4j和LDAP。spring-doc.cadn.net.cn

对于单个参数 是 GraphQL 输入类型,QuerydslDataFetcher嵌套一个层级下降,并使用参数子映射中的值。

如果仓库是ReactiveQuerydslPredicateExecutor,建造者回归DataFetcher<Mono<Account>>DataFetcher<Flux<Account>>. Spring Data 支持这种MongoDB 和 Neo4j 的变体。spring-doc.cadn.net.cn

构建设置

要在你的构建中配置 Querydsl,请按照官方参考文档作:spring-doc.cadn.net.cn

dependencies {
	//...

	annotationProcessor "com.querydsl:querydsl-apt:$querydslVersion:jpa",
			'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final',
			'javax.annotation:javax.annotation-api:1.3.2'
}

compileJava {
	 options.annotationProcessorPath = configurations.annotationProcessor
}
<dependencies>
	<!-- ... -->
	<dependency>
		<groupId>com.querydsl</groupId>
		<artifactId>querydsl-apt</artifactId>
		<version>${querydsl.version}</version>
		<classifier>jpa</classifier>
		<scope>provided</scope>
	</dependency>
	<dependency>
		<groupId>org.hibernate.javax.persistence</groupId>
		<artifactId>hibernate-jpa-2.1-api</artifactId>
		<version>1.0.2.Final</version>
	</dependency>
	<dependency>
		<groupId>javax.annotation</groupId>
		<artifactId>javax.annotation-api</artifactId>
		<version>1.3.2</version>
	</dependency>
</dependencies>
<plugins>
	<!-- Annotation processor configuration -->
	<plugin>
		<groupId>com.mysema.maven</groupId>
		<artifactId>apt-maven-plugin</artifactId>
		<version>${apt-maven-plugin.version}</version>
		<executions>
			<execution>
				<goals>
					<goal>process</goal>
				</goals>
				<configuration>
					<outputDirectory>target/generated-sources/java</outputDirectory>
					<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
				</configuration>
			</execution>
		</executions>
	</plugin>
</plugins>

webmvc-http示例使用Querydsl文物仓库.spring-doc.cadn.net.cn

定制

QuerydslDataFetcher支持自定义 GraphQL 参数如何绑定到属性上以创建 Querydsl谓语. 默认情况下,参数被绑定为“等于”每个可用属性。为了自定义,你可以使用QuerydslDataFetcher架构工人 提供QuerydslBinderCustomizer.spring-doc.cadn.net.cn

一个仓库本身可以是QuerydslBinderCustomizer. 这是自动检测的并在自动注册过程中透明地应用。然而,当手动构建一个QuerydslDataFetcher你需要使用架构方法来应用。spring-doc.cadn.net.cn

QuerydslDataFetcher支持接口和DTO投影以转换查询结果然后返回这些数据以便进一步处理GraphQL。spring-doc.cadn.net.cn

想了解什么是投影,请参考 Spring Data 文档。想了解如何在 GraphQL 中使用投影,请参见 Selection Set 与 Projections

要在 Querydsl 仓库中使用 Spring Data 投影,可以创建一个投影接口或者创建一个目标 DTO 类,并通过项目As获得数据费彻生成目标类型:spring-doc.cadn.net.cn

class Account {

	String name, identifier, description;

	Person owner;
}

interface AccountProjection {

	String getName();

	String getIdentifier();
}

// For single result queries
DataFetcher<AccountProjection> dataFetcher =
		QuerydslDataFetcher.builder(repository).projectAs(AccountProjection.class).single();

// For multi-result queries
DataFetcher<Iterable<AccountProjection>> dataFetcher =
		QuerydslDataFetcher.builder(repository).projectAs(AccountProjection.class).many();

自动注册

如果仓库被注释为@GraphQlRepository,自动注册 对于尚未注册的查询数据费彻以及返回类型 与仓库域类型匹配。这包括单值查询、多值查询 查询,以及分页查询。spring-doc.cadn.net.cn

默认情况下,查询返回的 GraphQL 类型名称必须与简单名称相匹配 属于仓库域类型。如果需要,你可以使用类型名称属性@GraphQlRepository以指定目标 GraphQL 类型名称。spring-doc.cadn.net.cn

对于分页查询,仓库域类型的简单名称必须与连接类型名称,但不含连接结尾(例如:比赛连接).自动注册时,分页采用20条偏移方式 每页。spring-doc.cadn.net.cn

自动注册检测给定仓库是否实现了QuerydslBinderCustomizer和 透明地通过QuerydslDataFetcher架构方法。spring-doc.cadn.net.cn

自动注册通过内置功能实现RuntimeWiringConfigurer这可以是 来源QuerydslDataFetcher.启动Starters自动启动 检测@GraphQlRepository并用它们来初始化RuntimeWiringConfigurer跟。spring-doc.cadn.net.cn

自动注册通过呼叫应用自定义定制(建造)在仓库实例中,如果你的仓库 实现QuerydslBuilderCustomizerReactiveQuerydslBuilderCustomizer分别。spring-doc.cadn.net.cn

示例查询

Spring Data 支持使用示例查询来获取数据。示例查询(QBE)是一种简单的查询技术,不需要 你可以通过商店特定的查询语言来写查询。spring-doc.cadn.net.cn

首先声明一个仓库QueryByExampleExecutor:spring-doc.cadn.net.cn

public interface AccountRepository extends Repository<Account, Long>,
			QueryByExampleExecutor<Account> {
}

QueryByExampleDataFetcher将仓库转变为数据费彻:spring-doc.cadn.net.cn

// For single result queries
DataFetcher<Account> dataFetcher =
		QueryByExampleDataFetcher.builder(repository).single();

// For multi-result queries
DataFetcher<Iterable<Account>> dataFetcher =
		QueryByExampleDataFetcher.builder(repository).many();

// For paginated queries
DataFetcher<Iterable<Account>> dataFetcher =
		QueryByExampleDataFetcher.builder(repository).scrollable();

你现在可以注册上述内容数据费彻通过一个RuntimeWiringConfigurer.spring-doc.cadn.net.cn

数据费彻使用 GraphQL 参数映射来创建 并以此为示例对象来获取数据。Spring Data 支持QueryByExampleDataFetcher适用于JPA、MongoDB、Neo4j和Redis。spring-doc.cadn.net.cn

对于单个参数 是 GraphQL 输入类型,QueryByExampleDataFetcher嵌套一层,并绑定参数子映射的值。

如果仓库是ReactiveQueryByExampleExecutor,建造者回归DataFetcher<Mono<Account>>DataFetcher<Flux<Account>>.Spring Data 支持这一点 适用于 MongoDB、Neo4j、Redis 和 R2dbc 的变体。spring-doc.cadn.net.cn

构建设置

示例查询功能已包含在 Spring 数据模块中,适用于以下数据存储 它是支持的,所以不需要额外设置来启用。spring-doc.cadn.net.cn

定制

QueryByExampleDataFetcher支持接口和DTO投影以实现查询转换 结果后返回进行进一步的GraphQL处理。spring-doc.cadn.net.cn

如需了解什么是预测,请参阅春季数据文档。 要理解投影在GraphQL中的作用,请参见选择集与投影

要使用 Spring Data 投影和示例查询仓库,可以创建一个投影接口 或者一个目标DTO类,并通过项目As获得数据费彻生成目标类型:spring-doc.cadn.net.cn

class Account {

	String name, identifier, description;

	Person owner;
}

interface AccountProjection {

	String getName();

	String getIdentifier();
}

// For single result queries
DataFetcher<AccountProjection> dataFetcher =
		QueryByExampleDataFetcher.builder(repository).projectAs(AccountProjection.class).single();

// For multi-result queries
DataFetcher<Iterable<AccountProjection>> dataFetcher =
		QueryByExampleDataFetcher.builder(repository).projectAs(AccountProjection.class).many();

自动注册

如果仓库被注释为@GraphQlRepository,自动注册 对于尚未注册的查询数据费彻以及返回类型 与仓库域类型匹配。这包括单值查询、多值查询 查询,以及分页查询。spring-doc.cadn.net.cn

默认情况下,查询返回的 GraphQL 类型名称必须与简单名称相匹配 属于仓库域类型。如果需要,你可以使用类型名称属性@GraphQlRepository以指定目标 GraphQL 类型名称。spring-doc.cadn.net.cn

对于分页查询,仓库域类型的简单名称必须与连接类型名称,但不含连接结尾(例如:比赛连接).自动注册时,分页采用20条偏移方式 每页。spring-doc.cadn.net.cn

自动注册通过内置功能实现RuntimeWiringConfigurer这可以是 来源QueryByExampleDataFetcher.启动Starters自动启动 检测@GraphQlRepository并用它们来初始化RuntimeWiringConfigurer跟。spring-doc.cadn.net.cn

自动注册通过呼叫应用自定义定制(建造)在仓库实例中,如果你的仓库 实现QueryByExampleBuilderCustomizerReactiveQueryByExampleBuilderCustomizer分别。spring-doc.cadn.net.cn

选择集与投影

一个常见的问题是,GraphQL 的选择集与 Spring Data 预测相比如何?各自扮演什么角色?spring-doc.cadn.net.cn

简短的回答是,Spring for GraphQL 并不是一个能转换 GraphQL 的数据网关 直接对SQL或JSON查询进行查询。相反,它让你可以利用现有的春季 技术上并不假设GraphQL模式与 底层数据模型。这就是为什么需要以客户端为驱动的选择和服务器端转型 数据模型可以发挥互补的作用。spring-doc.cadn.net.cn

为了更好地理解,考虑 Spring Data 推广领域驱动(DDD)设计为 管理数据层复杂性的推荐方法。在DDD中,这很重要 以遵守总量的约束。根据定义,聚合仅当 全部加载,因为部分负载的聚合可能会对 聚合功能。spring-doc.cadn.net.cn

在Spring Data中,你可以选择是直接暴露聚合,还是 是否在返回为GraphQL之前对数据模型进行转换 结果。有时候只要做前者就够了,默认情况下,QuerydslQuery by Example 集成会把 GraphQL 转换起来 选择集进入属性路径暗示底层的Spring数据模块使用 限制选择。spring-doc.cadn.net.cn

在其他情况下,简化甚至转换底层数据模型是有用的 以适应GraphQL模式。Spring Data 通过接口支持此功能 以及DTO预测。spring-doc.cadn.net.cn

界面投影定义了一组固定的属性,用于揭示性质可能或 可能不是,取决于数据存储查询结果。有两种 接口投影,这两者都决定了从底层加载哪些属性 数据来源:spring-doc.cadn.net.cn

DTO投影提供了更高的自定义层次,因为你可以放置变换 代码可以是在构造函数或 getter 方法中编写。spring-doc.cadn.net.cn

DTO 投影是从查询中实现的,其中各个属性为 由投影本身决定。DTO 投影通常用于全 args 构造子(例如 Java 记录),因此只有当所有 必填字段(或列)是数据库查询结果的一部分。spring-doc.cadn.net.cn

滚动

正如分页中所述,GraphQL 光标连接规范定义了 分页机制连接,边缘页面信息模式类型,而 GraphQL Java 提供等效的 Java 类型表示。spring-doc.cadn.net.cn

Spring for GraphQL 内置了连接适配器用于适应 Spring Data 分页类型透明。你可以配置那个 如下:spring-doc.cadn.net.cn

CursorStrategy<ScrollPosition> strategy = CursorStrategy.withEncoder(
		new ScrollPositionCursorStrategy(),
		CursorEncoder.base64()); (1)

GraphQLTypeVisitor visitor = ConnectionFieldTypeVisitor.create(List.of(
		new WindowConnectionAdapter(strategy),
		new SliceConnectionAdapter(strategy))); (2)

GraphQlSource.schemaResourceBuilder()
		.schemaResources(..)
		.typeDefinitionConfigurer(..)
		.typeVisitors(List.of(visitor)); (3)
1 制定转化策略卷轴位置连接到Base64编码的光标。
2 创建类型访问者以适应返回数据费彻s.
3 登记访客类型。

在请求端,控制器方法可以声明ScrollSubrange方法参数来分页 或者倒着。要让这个功能生效,你必须声明一个光标策略支持卷轴位置像豆子一样。spring-doc.cadn.net.cn

启动Starters会声明CursorStrategy<ScrollPosition>豆子,并注册了ConnectionFieldTypeVisitor如上所示,如果Spring Data在类路径上。spring-doc.cadn.net.cn

键盘组位置

KeysetScrollPosition(关键集滚动位置),光标需要由一个键集创建,即 本质上是地图关键值对的集合。为了决定如何从键集创建光标, 你可以配置滚动位置游标策略CursorStrategy<Map<String, Object>>. 默认情况下,JsonKeysetCursorStrategy写入密钥集地图转为JSON。这在 简单的,比如字符串、布尔、整数和双,但其他的则无法恢复到 同一种类型,但没有目标类型信息。Jackson 库有默认的打字功能 可以包含 JSON 中的类型信息。为了安全使用,您必须指定一份以下列表 允许的类型。例如:spring-doc.cadn.net.cn

PolymorphicTypeValidator validator = BasicPolymorphicTypeValidator.builder()
		.allowIfBaseType(Map.class)
		.allowIfSubType(ZonedDateTime.class)
		.build();

ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTyping(validator, ObjectMapper.DefaultTyping.NON_FINAL);

然后你可以创建JsonKeysetCursorStrategy:spring-doc.cadn.net.cn

ObjectMapper mapper = ... ;

CodecConfigurer configurer = ServerCodecConfigurer.create();
configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper));
configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper));

JsonKeysetCursorStrategy strategy = new JsonKeysetCursorStrategy(configurer);

默认情况下,如果JsonKeysetCursorStrategy在没有CodecConfigurer以及 Jackson 库在类路径上,应用了上述自定义日期,日历,以及任意类型java.time.spring-doc.cadn.net.cn

排序

Spring for GraphQL 定义了一个排序策略创造排序从GraphQL参数中获得。摘要排序策略用抽象方法实现该契约以提取排序 方向和属性。以支持以下内容排序作为控制器方法参数, 你需要申报排序策略豆。spring-doc.cadn.net.cn