在一个项目中,我将graphql-java和spring boot与 postgreSQL 数据库一起使用。现在我想使用3.0.0 版本发布的订阅功能。遗憾的是,关于订阅功能应用的信息还不是很成熟。
使用订阅实现实时功能的方法如何?graphql-java
在一个项目中,我将graphql-java和spring boot与 postgreSQL 数据库一起使用。现在我想使用3.0.0 版本发布的订阅功能。遗憾的是,关于订阅功能应用的信息还不是很成熟。
使用订阅实现实时功能的方法如何?graphql-java
从最近的 graphql-java 版本开始,完全支持订阅。DataFetcher
订阅的 必须返回 a ,org.reactivestreams.Publisher
graphql-java 将负责将查询函数映射到结果。
该功能有很好的文档记录,并且在官方 repo 中有一个使用 web 套接字的完整示例。
如果您有一个响应式数据源(例如,带有响应式驱动程序的 Mongo,或者可能是R2DBC支持的任何东西),那么您已经准备就绪。只需使用@Tailable
,Spring Data 就已经为您提供了一个Flux
(它实现了Publisher
),您无需做任何其他事情。
至于更手动的 Spring 特定实现,我无法想象使用Spring 自己的事件机制(这里也是一个不错的教程)来支持Publisher
.
每次有传入订阅时,使用应用程序上下文创建并注册一个新侦听器:context.addApplicationListener(listener)
它将发布到正确的Publisher
. 例如在DataFetcher
:
// Somehow create a publisher, probably using Spring's Reactor project. Or RxJava.
Publisher<ResultObject> publisher = ...;
//The listener reacts on application events and pushes new values through the publisher
ApplicationListener listener = createListener(publisher);
context.addApplicationListener(listener);
return publisher;
当 Web 套接字断开连接或您以某种方式知道事件流已完成时,您必须确保删除侦听器。
请注意,我实际上没有尝试过任何这些,我只是在大声思考。
另一种选择是直接使用 Reactor(有或没有 Spring WebFlux)。这里有一个使用 Reactor 和 WebSocket(通过GraphQL SPQR Spring Boot Starter)的示例。
你创建一个Publisher
这样的:
//This is really just a thread-safe wrapper around Map<String, Set<FluxSink<Task>>>
private final ConcurrentMultiRegistry<String, FluxSink<Task>> subscribers = new ConcurrentMultiRegistry<>();
@GraphQLSubscription
public Publisher<Task> taskStatusChanged(String taskId) {
return Flux.create(subscriber -> subscribers.add(taskId, subscriber.onDispose(() -> subscribers.remove(taskId, subscriber))), FluxSink.OverflowStrategy.LATEST);
}
然后从其他地方(可能是相关的突变或反应性存储)推送新值,如下所示:
subscribers.get(taskId).forEach(subscriber -> subscriber.next(task));
例如
@GraphQLMutation
public Task updateTask(@GraphQLNonNull String taskId, @GraphQLNonNull Status status) {
Task task = repo.byId(taskId); //find the task
task.setStatus(status); //update the task
repo.save(task); //persist the task
//Notify all the subscribers following this task
subscribers.get(taskId).forEach(subscriber -> subscriber.next(task));
return task;
}
使用 SPQR Spring Starter,这就是为您提供与 Apollo 兼容的订阅实现所需的全部内容。
作为记录:这是另一个非常好的、紧凑的示例,它实现了 GraphQL 的基本功能查询、突变和订阅:https ://github.com/npalm/blog-graphql-spring-service
我遇到了同样的问题,我在 lib 上添加了与 spring boot 集成。我找到了graphql-java,但是,它似乎只支持模式级别的“订阅”,它不对该功能执行任何跨国支持。这意味着您可能需要自己实现它。
请参考https://github.com/graphql-java/graphql-java/blob/master/docs/schema.rst#subscription-support