introproventures / graphql-jpa-query

Generate GraphQL Query Api for your JPA Entity Models
https://github.com/introproventures/graphql-jpa-query
Apache License 2.0
197 stars 54 forks source link

Reactive and webflux ? #92

Closed darkrift closed 5 years ago

darkrift commented 5 years ago

I am trying to setup a reactive environment but the starter is only for webmvc :

The bean 'requestMappingHandlerAdapter', defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.class] and overriding is disabled.

igdianov commented 5 years ago

@darkrift I don't think it is directly related to Graphql-jpa-query. In SB 2.1, bean overriding has been disabled by default. You can try to enable it, but I don't think it is a good idea. You can also try disable SB Reactive auto configuration. Do you @ComponentScan in your application?

darkrift commented 5 years ago

The problem is that graphql-jpa-query-boot-starter includes the following dependency :

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

However, in the app I am building, I am using spring-boot-starter-webflux which conflicts with spring-boot-starter-web.

spring-boot-starter-webflux (or one of it's dependencies) injects a bean with name 'requestMappingHandlerAdapter' to map the incoming request from webflux/reactive to spring components.

What I think is needed is another spring boot starter, similar to how they did for graphql-java-spring, to allow people use your library but from the webflux world.

This might bring some problems though with transactions for lazy loading as spring-boot-web seems to inject OpenEntityManagerInViewInterceptor and ensure there is a transaction for the duration of the request while there is no such interceptor with webflux.

igdianov commented 5 years ago

@darkrift Yes, I see. You can try to <exclude> spring-boot-starter-web in your project inside graphql-jpa-query-boot-starter dependency. Let me know how it works.

molexx commented 5 years ago

Reactive/webflux doesn't support JPA... AFAIK?

igdianov commented 5 years ago

JPA Hibernate provider does not support Spring R2DBC as well as GraphQL Rest Controller does not support Flux return types, so there is not much gain to use Webflux in the first place . I can add support for it via another starter if there is interest.

darkrift commented 5 years ago

@molexx there is no relation between webflux and JPA. One is to route requests to your “controllers”, the other is your ORM between your business logic code and the database. How you return the data is another story but they are not linked.

Spring boot adds an interceptor when configured with webmvc to open a transaction for the request. This can be disabled and is not necessary.

You can also map REST controller with webflux, so long u return the proper type (Mono objects).

molexx commented 5 years ago

Webflux expects reactive/async/non-blocking all the way down, which JPA and JDBC cannot provide. Trying to wrap JPA in there will block threads that webflux/netty isn't expecting to be blocked so at best any supposed gains of webflux will be lost and at worst everything will grind to a halt. All the official examples/demos use mongo which has reactive support in spring-data but is not JPA.

@igdianov there is incubating support in spring-data for R2DBC but it's not JPA, it's a very cut down ORM with its own annotations so would require a lot of work in this library.

igdianov commented 5 years ago

@molexx I am not planning to support R2DBC at the moment and in the future for now.

@darkrift It should be possible to provide Rest controller with Webflux by exposing GraphQL.executeAsync via GraphQLExecutor and then map CompletableFuture result into Mono<> return type. However, it adds a lot of plumbing to bridge the gap between blocking JDBC, async GraphQL execution and reactive Webflux. I think there will be not much gain in performance by adding more complexity with Webflux.

darkrift commented 5 years ago

Fair enough, maybe when R2DBC and JPA will fill the missing links will that be a better option.