将多个 graphQL 模式文件映射到单独的解析器 - Spring 引导
Mapping multiple graphQL schema files to separate resolvers - Spring Boot
我发现很难将查询与一个模式文件分开。我想要这样的东西:
car.graphqls
type Query {
car(id: ID!): Car
}
type Car {
id: ID!,
name: String!
}
house.graphqls
type Query {
house(id: ID!): House
}
type House {
id: ID!,
owner: String,
street: String
}
我搜索了很多,但找不到写两个 java 类 并在其中一个中实现 getHouse()
而在另一个中实现 getCar()
的方法。
@Component
public class CarQuery implements GraphQLQueryResolver {
@Autowired
private CarService carService;
public List<Car> getCar(final int id) {
return this.carService.getCar(id);
}
}
public class HouseQuery implements GraphQLQueryResolver {
@Autowired
private HouseService houseService;
public List<House> getHouse(final int id) {
return this.houseService.getHouse(id);
}
}
我发现我正在使用的 graphql-java-tools
包将搜索项目并找到所有模式文件(以 .graphqls
结尾),但是我上面显示的代码给出了我这个错误:
Caused by: com.coxautodev.graphql.tools.FieldResolverError: No method found with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment] as the last argument), in priority order:
com.example.polls.resolvers.CarQuery.house(~count)
com.example.polls.resolvers.CarQuery.getHouse(~count)
我还发现一些建议,我只需要在模式文件中有一个根查询,并扩展模式文件中的所有其他查询类型。我试着写信给 house.graphqls
这样的东西,但失败了:
extend Type Query {
house(id: ID!): House
}
有没有办法告诉 graphql 和 java 我想将哪个模式文件映射到哪个 java 解析器文件?
多个架构文件
Graphql-java-tools
将找到所有 .graphqls
文件来构建模式实例。多个模式文件开箱即用。
多个解析器
每个解析器组件必须实现 GraphQLQueryResolver
或 GraphQLMutationResolver
并且可以被 spring 引导扫描。确保它有一个 @Component
注释并且在 spring @ComponentScan
basePackages 之一中。
错误
No method found with any of the following signature
表示 graphql-tools 无法找到方法与签名匹配的解析器组件。在这种情况下,HouseQuery 解析器缺少 @Component 注释。
感谢 AllirionX。您的回答很有帮助。
我只想向所有正在寻找答案的人总结最终解决方案,即如何创建多个模式文件,每个模式文件中都有单独的查询类型,并使用 GraphQLQueryResolver 将这些查询类型映射到不同的 Java 组件。
My Spring Boot project structure
我有两个架构文件 A.graphqls 和 B.graphqls。
A.graphqls
---------------
type Person {
id: ID!,
name: String
}
type Query {
getPerson(id: Int):Person
}
type Mutation {
createPerson(name: String):Int
}
B.graphqls
---------------
type Book {
id: ID!,
title: String,
owner: Person
}
extend type Query {
getBooks(count: Int):[Book]
}
extend type Mutation {
deleteBook(id: Int):Int
}
schema {
query: Query,
mutation: Mutation
}
我将解释我所了解的关于我们需要遵循的有关该主题的规则(我不保证这一切都是必要的,但这就是我设法让它按照我希望的方式工作的方式)。
这里的关键是只有一个模式定义。在哪个文件中无关紧要(A.graphqls 或 B.graphqls 或 C.graphqls...) - 例如,我将其添加到底部的 B.graphqls 文件中。
此外,一个文件中只能有一个 "type Query" 定义。在所有其他模式文件中,您将需要使用 "extend type Query" 扩展该类型(是的,我知道,现在这很有意义......)。您在哪个架构文件中为不相关的查询执行主要定义。本段中的所有内容也适用于突变。
您可以在另一个 .graphqls 文件中使用一个 .graphqls 文件中定义的类型。它会得到认可。因此,在此示例中,您可以在 B.graphqls.
中使用 Person 类型引用
Java 解析器:
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import graphql.demo.model.Person;
import graphql.demo.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class AQuery implements GraphQLQueryResolver {
@Autowired
private PersonService personService;
public Person getPerson(final int id) {
return this.personService.getPerson(id);
}
}
第二个...
@Component
public class BQuery implements GraphQLQueryResolver {
@Autowired
private BookService bookService;
public List<Book> getBooks(final int count) {
return this.bookService.getBooks(count);
}
}
此 class 的名称并不重要。我们也可以只有一个 class 实现 GraphQLQueryResolver,我们可以从 A.graphqls 和 B.graphqls 文件(getBooks() 和 getPerson() 方法)实现所有查询方法。只要我们实现了所有方法,我们在哪个解析器 class 中实现它并不重要 graphql-java 会找到它。
这同样适用于使用 GraphQLMutationResolver 的突变。
我的 github 上有完整的工作示例(MySQL、Spring Boot、React with Apollo 客户端),您可以查看。还有 mysql 用于生成项目中使用的数据库的脚本。有很多表,但只是为了测试目的,重要的是我上面解释的文件结构和文件。如果您对客户端应用不感兴趣,当然可以使用 graphiql 对其进行测试。
https://github.com/dusko-dime/spring-react-graphql
希望这对某人有所帮助,感谢您再次帮助我:)
您的解析器名称也可能存在问题
请确保您指定的 Resolver 方法名称与您在 GraphQL Schema
中定义的名称相同
我发现很难将查询与一个模式文件分开。我想要这样的东西:
car.graphqls
type Query {
car(id: ID!): Car
}
type Car {
id: ID!,
name: String!
}
house.graphqls
type Query {
house(id: ID!): House
}
type House {
id: ID!,
owner: String,
street: String
}
我搜索了很多,但找不到写两个 java 类 并在其中一个中实现 getHouse()
而在另一个中实现 getCar()
的方法。
@Component
public class CarQuery implements GraphQLQueryResolver {
@Autowired
private CarService carService;
public List<Car> getCar(final int id) {
return this.carService.getCar(id);
}
}
public class HouseQuery implements GraphQLQueryResolver {
@Autowired
private HouseService houseService;
public List<House> getHouse(final int id) {
return this.houseService.getHouse(id);
}
}
我发现我正在使用的 graphql-java-tools
包将搜索项目并找到所有模式文件(以 .graphqls
结尾),但是我上面显示的代码给出了我这个错误:
Caused by: com.coxautodev.graphql.tools.FieldResolverError: No method found with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment] as the last argument), in priority order:
com.example.polls.resolvers.CarQuery.house(~count)
com.example.polls.resolvers.CarQuery.getHouse(~count)
我还发现一些建议,我只需要在模式文件中有一个根查询,并扩展模式文件中的所有其他查询类型。我试着写信给 house.graphqls
这样的东西,但失败了:
extend Type Query {
house(id: ID!): House
}
有没有办法告诉 graphql 和 java 我想将哪个模式文件映射到哪个 java 解析器文件?
多个架构文件
Graphql-java-tools
将找到所有 .graphqls
文件来构建模式实例。多个模式文件开箱即用。
多个解析器
每个解析器组件必须实现 GraphQLQueryResolver
或 GraphQLMutationResolver
并且可以被 spring 引导扫描。确保它有一个 @Component
注释并且在 spring @ComponentScan
basePackages 之一中。
错误
No method found with any of the following signature
表示 graphql-tools 无法找到方法与签名匹配的解析器组件。在这种情况下,HouseQuery 解析器缺少 @Component 注释。
感谢 AllirionX。您的回答很有帮助。
我只想向所有正在寻找答案的人总结最终解决方案,即如何创建多个模式文件,每个模式文件中都有单独的查询类型,并使用 GraphQLQueryResolver 将这些查询类型映射到不同的 Java 组件。
My Spring Boot project structure
我有两个架构文件 A.graphqls 和 B.graphqls。
A.graphqls
---------------
type Person {
id: ID!,
name: String
}
type Query {
getPerson(id: Int):Person
}
type Mutation {
createPerson(name: String):Int
}
B.graphqls
---------------
type Book {
id: ID!,
title: String,
owner: Person
}
extend type Query {
getBooks(count: Int):[Book]
}
extend type Mutation {
deleteBook(id: Int):Int
}
schema {
query: Query,
mutation: Mutation
}
我将解释我所了解的关于我们需要遵循的有关该主题的规则(我不保证这一切都是必要的,但这就是我设法让它按照我希望的方式工作的方式)。
这里的关键是只有一个模式定义。在哪个文件中无关紧要(A.graphqls 或 B.graphqls 或 C.graphqls...) - 例如,我将其添加到底部的 B.graphqls 文件中。
此外,一个文件中只能有一个 "type Query" 定义。在所有其他模式文件中,您将需要使用 "extend type Query" 扩展该类型(是的,我知道,现在这很有意义......)。您在哪个架构文件中为不相关的查询执行主要定义。本段中的所有内容也适用于突变。
您可以在另一个 .graphqls 文件中使用一个 .graphqls 文件中定义的类型。它会得到认可。因此,在此示例中,您可以在 B.graphqls.
中使用 Person 类型引用
Java 解析器:
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import graphql.demo.model.Person;
import graphql.demo.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class AQuery implements GraphQLQueryResolver {
@Autowired
private PersonService personService;
public Person getPerson(final int id) {
return this.personService.getPerson(id);
}
}
第二个...
@Component
public class BQuery implements GraphQLQueryResolver {
@Autowired
private BookService bookService;
public List<Book> getBooks(final int count) {
return this.bookService.getBooks(count);
}
}
此 class 的名称并不重要。我们也可以只有一个 class 实现 GraphQLQueryResolver,我们可以从 A.graphqls 和 B.graphqls 文件(getBooks() 和 getPerson() 方法)实现所有查询方法。只要我们实现了所有方法,我们在哪个解析器 class 中实现它并不重要 graphql-java 会找到它。 这同样适用于使用 GraphQLMutationResolver 的突变。
我的 github 上有完整的工作示例(MySQL、Spring Boot、React with Apollo 客户端),您可以查看。还有 mysql 用于生成项目中使用的数据库的脚本。有很多表,但只是为了测试目的,重要的是我上面解释的文件结构和文件。如果您对客户端应用不感兴趣,当然可以使用 graphiql 对其进行测试。
https://github.com/dusko-dime/spring-react-graphql
希望这对某人有所帮助,感谢您再次帮助我:)
您的解析器名称也可能存在问题 请确保您指定的 Resolver 方法名称与您在 GraphQL Schema
中定义的名称相同