Spring boot+graphql
一、使用graphql-java-tools方式
com.graphql-java-kickstart
graphql-java-tools
5.6.0
com.graphql-java-kickstart
graphiql-spring-boot-starter
5.0.4
schema.graphqls
type Query {
books: [Book!]
}
type Book {
id: Int!
name: String!
author: Author!
}
type Author {
id: Int!
name: String!
}
对应的java class
class Book {
private int id;
private String name;
private int authorId;
// constructor
// getId
// getName
// getAuthorId
}
class Author {
private int id;
private String name;
// constructor
// getId
// getName
}
Book-Resolver
class BookResolver implements GraphQLResolver {
private AuthorRepository authorRepository;
public BookResolver(AuthorRepository authorRepository) {
this.authorRepository = authorRepository;
}
public Author author(Book book) {
return authorRepository.findById(book.getAuthorId());
}
}
Query-Resolver
class Query implements GraphQLQueryResolver {
private BookRepository bookRepository;
public Query(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public List books() {
return bookRepository.findAll();
}
}
Type Query 没有对应的java class,如果type 中的所有字段和java class成员变量一致,则该type可以不用定义Resolver.
graphql type中的字段映射Java class字段的优先级
对于graphql objectType中的字段映射为java class字段顺序如下:
例如:
上述type Book中的name字段的映射顺序为:
graphql type中的字段映射Resolver的优先级:
注:Resolver的映射优先级高于Java Class,首先在Resolver中查找,如果没找到,才会在Java class中查找 :例如上述type Book中的author字段,会首先映射为BookResolver重的author(Book)方法。
解析schema.graphqls,创建Graphql对象:
import com.coxautodev.graphql.tools.SchemaParser;
GraphQLSchema schema = SchemaParser.newParser().file("schema.graphqls")
.resolvers(new QueryResolver(), new BookResolver())
.build()
.makeExecutableSchema();
GraphQL graphQL = GraphQL.newGraphQL(schema).build();
// 执行查询
ExecutionResult result = graphQL.execute(query);
Map map = result.toSpecification();
二、不使用Resolver
schema.graphqls:
type Query {
bookById(id: ID): Book
}
type Book {
id: ID
name: String
pageCount: Int
author: Author
}
type Author {
id: ID
firstName: String
lastName: String
}
加载schema.graphqls,创建GraphQL对象:
import graphql.schema.idl.SchemaParser;
@Value("classpath:schema.graphqls")
Resource resource;
@PostConstruct
private void loadSchema() throws Exception {
File schemaFile = resource.getFile();
GraphQLSchema schema = buildSchema(schemaFile);
graphQL = GraphQL.newGraphQL(schema).build();
}
private GraphQLSchema buildSchema(File file) throws Exception {
TypeDefinitionRegistry registry = new SchemaParser().parse(file);
RuntimeWiring runtimeWiring = buildWiring();
SchemaGenerator schemaGenerator = new SchemaGenerator();
return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
}
private RuntimeWiring buildWiring() {
return RuntimeWiring.newRuntimeWiring()
// 为每个graphql type的字段提供DataFetcher
.type(newTypeWiring("Query")
.dataFetcher("bookById", graphQLDataFetchers.getBookByIdDataFetcher()))
.type(newTypeWiring("Book")
.dataFetcher("author", graphQLDataFetchers.getAuthorDataFetcher()))
.build();
}
DataFetcher:
@Component
public class GraphQLDataFetchers {
private static List
注:这种方式,并不要求一定要提供type对应的java class,只要在对应的DataFetcher中返回符合type的数据格式即可
三、方式三,不使用graphql-java-tools
不定义schema.graphqls,以编码的方式创建graphql type。
定义graphql type:
GraphQLObjectType fooType = newObject()
.name("Foo")
.field(newFieldDefinition()
.name("bar")
.type(GraphQLString))
.build();
上述代码相当于使用schema方式创建了如下graphql type:
type Foo {
bar: String
}
为类型的field指定DataFetcher:
DataFetcher fooDataFetcher = environment -> {
// environment.getSource() is the value of the surrounding
// object. In this case described by objectType
Foo value = perhapsFromDatabase(); // Perhaps getting from a DB or whatever
return value;
}
GraphQLObjectType objectType = newObject()
.name("ObjectType")
.field(newFieldDefinition()
.name("foo")
.type(GraphQLString)
.dataFetcher(fooDataFetcher))
.build();
完整的代码:
// 定义一个type Query
/**
* 相当于 type QueryType{ hello: String }
*/
GraphQLObjectType queryType = newObject()
.name("QueryType")
.field(newFieldDefinition()
.name("hello")
.type(GraphQLString)
.dataFetcher(new StaticDataFetcher("world!"))
.build();
// 创建GraphQLSchema
GraphQLSchema schema = GraphQLSchema.newSchema()
.query(queryType)
.build();
// Make the schema executable
GraphQL executor = GraphQL.newGraphQL(graphQLSchema).build();
ExecutionResult executionResult = executor.execute("{hello}");
四、参考链接
https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/
https://www.graphql-java-kickstart.com/tools/
https://www.graphql-java.com/documentation/v11/