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

查看:23
本文介绍了graphql-java - 如何在 Spring Boot 中使用订阅?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个项目中,我使用 graphql-javaspring boot 使用 postgreSQL 数据库.现在我想使用订阅功能 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 特定实现,我无法想象使用 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天全站免登陆