graphql-java-如何在Spring Boot中使用订阅 [英] graphql-java - How to use subscriptions with spring boot?
问题描述
在一个项目中,我使用 graphql-java 带有PostgreSQL数据库的 spring boot .现在,我想使用 订阅功能 在版本3.0.0中发布.不幸的是,关于订阅功能的应用的信息还不是很成熟.
In a project I use graphql-java and spring boot with a postgreSQL Database. Now I would like to use the subscription feature published in version 3.0.0. Unfortunately, the information about the application of the subsciption function is not very mature.
如何使用带有订阅的 graphql-java
实现实时功能?
How is the approach to achieve real-time functionality using graphql-java
with subscriptions?
推荐答案
从最新的graphql-java版本开始,完全支持订阅.预订的 DataFetcher
必须返回 org.reactivestreams.Publisher
,graphql-java将负责在结果上映射查询功能.
As of recent graphql-java versions, subscriptions are fully supported. The DataFetcher
for a subscription must return a org.reactivestreams.Publisher
, and graphql-java will take care of mapping the query function over the results.
该功能很好地已记录,并且有
The feature is nicely documented and there's a complete example using web sockets available in the official repo.
如果您有反应性数据源(例如,具有反应性驱动程序的Mongo,或者可能是 R2DBC 支持),一切就绪.只需使用 @Tailable
和Spring Data已经为您提供了 Flux
(它实现了 Publisher
),您无需执行其他任何操作.
If you have a reactive data source in place (e.g. Mongo with a reactive driver, or probably anything that R2DBC supports), you're all set. Just use @Tailable
and Spring Data will already give you a Flux
(which implements Publisher
) and there's nothing else you need to do.
对于特定于Spring的更加手动的实现,我无法想象使用 )作为 Publisher
的基础.
As for a more manual Spring specific implementation, I can't imagine it being too hard to use Spring's own event mechanism (a nice tutorial here as well) to underlie the Publisher
.
每次有传入订阅时,请使用应用程序上下文创建并注册一个新的侦听器: context.addApplicationListener(listener)
,它将发布到正确的 Publisher
.例如.在 DataFetcher
中:
Every time there's an incoming subscription, create and register a new listener with the application context: context.addApplicationListener(listener)
that will publish to the correct Publisher
. E.g. in the 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套接字断开连接或以某种方式知道事件流已完成时,必须确保删除侦听器.
When the web socket disconnects or you somehow know the event stream is finished, you must make sure to remove the listener.
我实际上还没有尝试过任何一种方法,请注意,我只是在大声思考.
I haven't actually tried any of this, mind you, I'm just thinking aloud.
另一个选择是直接使用Reactor(带有或不带有Spring WebFlux).有一个使用Reactor和WebSocket的示例(通过 GraphQL SPQR Spring Boot Starter )
Another option is to use Reactor directly (with or without Spring WebFlux). There's a sample using Reactor and WebSocket (through GraphQL SPQR Spring Boot Starter) here.
您可以这样创建 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);
}
然后从其他地方(可能是相关的突变或反应性存储)推送新值,如下所示:
And then push new values from elsewhere (probably a related mutation or a reactive storage) like this:
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兼容的订阅实现所需要的全部内容.
With SPQR Spring Starter, this is all that's needed to get you an Apollo-compatible subscription implementation.
这篇关于graphql-java-如何在Spring Boot中使用订阅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!