graphql-java-如何在Spring Boot中使用订阅 [英] graphql-java - How to use subscriptions with spring boot?

查看:118
本文介绍了graphql-java-如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆