【问题标题】:Reactive GraphQL反应式 GraphQL
【发布时间】:2020-09-18 21:36:49
【问题描述】:

尝试实现响应式 graphql 并遇到一些问题。

pom 依赖,

<dependency>
            <groupId>com.graphql-java-kickstart</groupId>
            <artifactId>graphql-kickstart-spring-boot-starter-webflux</artifactId>
            <version>7.0.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.graphql-java-kickstart/graphql-kickstart-spring-boot-starter-tools -->
        <dependency>
            <groupId>com.graphql-java-kickstart</groupId>
            <artifactId>graphql-kickstart-spring-boot-starter-tools</artifactId>
            <version>7.0.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.graphql-java-kickstart/graphiql-spring-boot-starter -->
        <dependency>
            <groupId>com.graphql-java-kickstart</groupId>
            <artifactId>graphiql-spring-boot-starter</artifactId>
            <version>7.0.1</version>
        </dependency>

架构:-

type Query {

  store(storeId: Int!): Store!

  stores: [Store!]!
}

type Store {
  storeId: Int!
  name: String!
  address: String!
  city: String!
  zip: String!
}

解析器:-

@Component
public class StoreQuery implements GraphQLQueryResolver {

    @Autowired
    private final StoreDao dao;

    public Store store(int storeId) {
        return dao.findById(storeId);
    }

    public List<Store> stores() {
        return dao.findAll();
    }

}

这里,如果我返回 Flux 或 Mono,会出现以下错误。

 "class": "org.springframework.beans.factory.BeanCreationException",
              "msg": "Error creating bean with name 'schemaParser' defined in class path resource [graphql/kickstart/tools/boot/GraphQLJavaToolsAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [graphql.kickstart.tools.SchemaParser]: Factory method 'schemaParser' threw exception; nested exception is java.lang.ClassCastException: class graphql.kickstart.tools.ParameterizedTypeImpl cannot be cast to class java.lang.Class (graphql.kickstart.tools.ParameterizedTypeImpl is in unnamed module of loader 'app'; java.lang.Class is in module java.base of loader 'bootstrap')",


  "class": "java.lang.ClassCastException",
                  "msg": "class graphql.kickstart.tools.ParameterizedTypeImpl cannot be cast to class java.lang.Class (graphql.kickstart.tools.ParameterizedTypeImpl is in unnamed module of loader 'app'; java.lang.Class is in module java.base of loader 'bootstrap')",

所以,尝试以 List 的形式返回。

但是使用阻塞调用将 Flux 转换为 List 也会引发错误,

public List<Store> findAll() {
        return Flux.from(storeCollection.find()).collectList().block();
    }

这里,得到下面的错误。

Exception while fetching data (/stores) : block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-kqueue-2

使用 graphiql 进行测试。

http://localhost:8089/graphiql

【问题讨论】:

  • 您的问题解决了吗?如果可以,请您与 webflux 分享一些 graphql 的参考文档。

标签: graphql graphql-java


【解决方案1】:

正如错误提示,您不能在非阻塞 webflux 中使用阻塞操作。

public Flux<Store> findAll() {
    return Flux.fromIterable(storeCollection.find());
    or
    return Flux.fromStream(storeCollection.find());
}

【讨论】:

    【解决方案2】:

    您不能在非阻塞 webflux 中使用阻塞操作。如果你使用 kickstart v.7.0.1 你应该返回 CompletableFuture

    public CompletableFuture<List<Store>> findAll() {
        return Flux.fromIterable(dao.findAll())
                .collectList()
                .toFuture();
    }
    

    【讨论】:

      猜你喜欢
      • 2022-08-09
      • 2020-08-28
      • 2020-11-07
      • 2019-06-01
      • 2019-07-20
      • 1970-01-01
      • 1970-01-01
      • 2020-12-03
      • 2020-05-01
      相关资源
      最近更新 更多