
在spring boot结合webflux和graphql构建响应式应用时,开发者常会遇到一个常见错误:expected source object to be an instance of 'com.example.myobject' but instead got 'reactor.core.publisher.fluxjust'。这个错误通常发生在graphql查询解析器(query resolver)尝试返回flux<t>或mono<t>等响应式类型,但所使用的graphql集成库未能正确识别和处理这些类型时。
问题的核心在于,传统的graphql-java-tools库或旧版本的graphql-spring-boot-starter可能不完全支持Spring WebFlux的响应式编程模型,导致它们无法将Flux或Mono这样的Publisher类型正确地解包并映射到GraphQL Schema中定义的具体类型。GraphQL期望得到的是实际的数据对象(例如Page实例),而不是表示数据流的FluxJust对象。
要解决这个问题并实现Spring Boot WebFlux与GraphQL的响应式集成,关键在于选择正确的依赖并遵循Spring GraphQL的推荐实践。
首先,确保你的pom.xml文件中包含以下关键依赖。spring-boot-starter-graphql是Spring官方提供的GraphQL集成方案,它与Spring WebFlux有着良好的兼容性,能够原生支持响应式类型。同时,spring-boot-starter-webflux是构建响应式Web应用的基础。
<dependencies>
<!-- Spring Boot GraphQL Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>
<!-- Spring Boot WebFlux Starter (for reactive web capabilities) -->
<dependency>
<groupId>org.springframework.boot</
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- Reactor Core (usually pulled in by WebFlux, but good to ensure) -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
<!-- Other dependencies like MongoDB Reactive Driver if needed -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<!-- ... 其他依赖 ... -->
</dependencies>注意事项:
GraphQL Schema的定义必须与你的响应式返回类型相匹配。
对于Flux<T>: 如果你的数据获取器返回一个Flux,表示可能返回零个、一个或多个Page对象,那么在Schema中应该将其定义为列表类型。
type Page {
id: Int!
host: String
# ... 其他字段 ...
}
type Query {
getPages: [Page!]! # 定义为Page对象的列表,且列表本身和其中的元素都不可为null
}对于Mono<T>: 如果你的数据获取器返回一个Mono,表示最多返回一个Page对象,那么在Schema中应该将其定义为单个对象类型。
type Query {
getPageById(id: Int!): Page # 定义为单个Page对象
}请注意,如果Mono可能为空,则Page类型不应带有!(非空约束)。
使用spring-boot-starter-graphql后,数据获取器的实现方式更为简洁和现代化。推荐使用@Controller结合@QueryMapping或@SchemaMapping注解来定义GraphQL查询。
PageService.java (保持不变,返回Flux)
import reactor.core.publisher.Flux;
import org.springframework.stereotype.Service;
@Service
public class PageService {
public Flux<Page> getPages() {
// 模拟响应式数据流,实际中会从ReactiveMongoRepository等获取
return Flux.just(new Page(12, "example.com"), new Page(13, "test.org"));
}
}PageController.java (GraphQL查询控制器)
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
import reactor.core.publisher.Flux;
import org.springframework.beans.factory.annotation.Autowired;
@Controller
public class PageController {
private final PageService pageService;
@Autowired
public PageController(PageService pageService) {
this.pageService = pageService;
}
@QueryMapping // 对应GraphQL Schema中的getPages查询
public Flux<Page> getPages() {
return pageService.getPages();
}
}Page.java (MongoDB Document 示例)
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
@Document("pages")
public class Page {
@Id
private int id;
private String host;
private String path;
private String jobAnchorSelector;
private String jobLinkContains;
private int numberOfPages;
private int interval;
private Date lastScrapePerformed;
private String userUuid;
public Page() {
}
public Page(int id, String host) {
this.id = id;
this.host = host;
}
// Getters and Setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getHost() { return host; }
public void setHost(String host) { this.host = host; }
// ... 其他字段的getter和setter ...
@Override
public String toString() {
return "Page [id=" + id + ", host=" + host + "]";
}
}Spring GraphQL对Mono和Flux的处理有其默认行为:
在Spring Boot WebFlux应用中集成GraphQL并处理响应式类型,关键在于:
遵循这些最佳实践,你将能够有效地在Spring Boot WebFlux环境中构建高性能、响应式的GraphQL API。
以上就是构建Spring Boot WebFlux与GraphQL的响应式数据查询教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号