I have my data stored in mongodb and I'm trying to implemet subscription using graphql spqr and project reactive. I'm getting respones for when I'm trying to test mutations and query, but I keep on getting the following error message for subsctiptions:

{ "error": "Could not connect to websocket endpoint ws://localhost:8080/subscriptions. Please check if the endpoint url is correct." }

I've done some reserch on this issue and came accross this, including "spring-boot-starter-websocket" in my dependencies didn't solve this, anf I'm not using firefox as my browser for the playground gui.

I followed this example on how to implement subscriptions using graphql spqr, and when I trying to clone the project the subscription actualy worked just fine.

Can't fine any difference on my implementation from the project above... Here is my build.gradle file:

    configurations {

    compile.exclude module: 'spring-boot-starter-tomcat'
    compile.exclude group: 'org.apache.tomcat'

    compileOnly {
        extendsFrom annotationProcessor
    }
}

dependencies {

   
    // https://mvnrepository.com/artifact/de.flapdoodle.embed/de.flapdoodle.embed.mongo
    testImplementation group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '3.0.0'

    // https://mvnrepository.com/artifact/io.leangen.graphql/graphql-spqr-spring-boot-starter
    implementation group: 'io.leangen.graphql', name: 'graphql-spqr-spring-boot-starter', version: '0.0.6'

    implementation group: 'io.leangen.graphql', name: 'spqr', version: io_leangen_graphql_spqr

    // https://mvnrepository.com/artifact/com.graphql-java-kickstart/playground-spring-boot-starter
    implementation group: 'com.graphql-java-kickstart', name: 'playground-spring-boot-starter', version: '11.1.0'

    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.5.4'


    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb-reactive
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-mongodb-reactive', version: '2.5.4'

    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.5.4'

    compileOnly group: 'org.projectlombok', name: 'lombok', version: org_projectlombok_lombok_version
    annotationProcessor group: 'org.projectlombok', name: 'lombok', version: org_projectlombok_lombok_version
}

I'm using

compile.exclude module: 'spring-boot-starter-tomcat'
    compile.exclude group: 'org.apache.tomcat'

To start netty instead of tomcat

And here is my subsctiption implementation:

@Autowired
private ProductRepository productRepository;

private final ConcurrentMultiMap<Double, FluxSink<ProductDto>> subscribers = new ConcurrentMultiMap<>();

@GraphQLQuery
public Flux<ProductDto> getProducts(){
    return productRepository.findAll().map(AppUtils::ProductEntityToDto);
}

@GraphQLSubscription
public Publisher<ProductDto> taskStatusChanged(double price) {
    return Flux.create(subscriber -> subscribers.add(price, subscriber.onDispose(() -> subscribers.remove(price, subscriber))), FluxSink.OverflowStrategy.LATEST);
}

Is there something I'm missing in my code? Or a dependancy? Or any other configuration? Any help would be very appreciated...

1

There are 1 answers

2
Hantsy On

By default it seems GraphQl SPQR mapped the WebSocket subscription handling endpoint to /graphql, not the general /subscriptions in other GraphQL framework.

See the following info in console when the application is starting.

2021-10-09 12:50:02.653 DEBUG 14632 --- [    Test worker] o.s.w.s.s.s.WebSocketHandlerMapping      : Patterns [/graphql] in 'webSocketHandlerMapping'

It can be changed by customizing graphql.spqr.ws.endpoint property in your application.properties.

But it seems its GraphQL WebSocket subscription implementation is very confused, it does not follow the Appllo WebSocket subscription protocol or the new graphql-ws spec.