graphql-java - 如何使用spring boot订阅?

时间:2017-05-30 19:18:14

标签: java spring-boot graphql graphql-java

在项目中,我使用 graphql-java spring boot 和postgreSQL数据库。现在,我想使用3.0.0版中发布的 subscription feature 。不幸的是,关于subsciption函数的应用的信息还不是很成熟。

如何使用graphql-java订阅来实现实时功能的方法?

3 个答案:

答案 0 :(得分:4)

截至最近的graphql-java版本,完全支持订阅。订阅的DataFetcher必须返回org.reactivestreams.Publisher,而graphql-java将负责将查询函数映射到结果上。

该功能很好documented并且a complete example使用官方仓库中提供的网络套接字。

对于Spring特定的实现,我无法想象使用Spring's own event mechanism(一个很好的教程here)来构建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 Starterhere

您可以像这样创建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));

E.g。

@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兼容的订阅实现所需的一切。

答案 1 :(得分:0)

我遇到了同样的问题,我在lib上加入了与spring boot集成的问题。我找到了graphql-java,但是,它似乎只支持模式级别的“订阅”,它没有对此功能执行任何跨国支持。意思是你可能需要自己实现它。

请参阅https://github.com/graphql-java/graphql-java/blob/master/docs/schema.rst#subscription-support

答案 2 :(得分:0)

记录:这是另一个非常好的紧凑示例,它实现了GraphQL的基本功能查询,变异和订阅:https://github.com/npalm/blog-graphql-spring-service