这里就不再介绍GraphQL了,有兴趣的同学可以看https://blog.csdn.net/qq_40794266/article/details/102961334
导入依赖
org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE
org.springframework.boot
spring-boot-starter-web
com.graphql-java
graphql-java
11.0
org.apache.commons
commons-io
1.3.2
resources下创建User.graphqls文件
schema {
query: UserQuery
}
type UserQuery {
user(id:Long) : User
}
type User{
id:Long!
name:String
age:Int
}
创建User类
package cn.xiechuang.pojo;
public class User {
private Long id;
private String name;
private Integer age;
public User(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
编写controller(接收请求)
package cn.xiechuang.controller;
import graphql.GraphQL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
@Controller
public class GraphQLController {
@Autowired
private GraphQL graphQL;
@GetMapping("/graphql")
@ResponseBody
public Map graphql(@RequestParam("query") String query){
return graphQL.execute(query).toSpecification();
}
}
创建一个GraphQLProvider
package cn.xiechuang.graphql;
import cn.xiechuang.pojo.User;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileNotFoundException;
@Component
public class GraphQLProvider {
private GraphQL graphQL;
@PostConstruct
public void init() throws FileNotFoundException {
File file = ResourceUtils.getFile("classpath:user.graphqls");
GraphQLSchema graphQLSchema = createGraphQLSchema(file);
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
}
public GraphQLSchema createGraphQLSchema(File file){
SchemaGenerator schemaGenerator = new SchemaGenerator();
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry typeRegistry = schemaParser.parse(file);
return schemaGenerator.makeExecutableSchema(typeRegistry, buildResolver());
}
public RuntimeWiring buildResolver(){
return RuntimeWiring.newRuntimeWiring()
.type("UserQuery",builder ->
builder.dataFetcher("user",
dataFetchingEnvironment -> {
Long id = dataFetchingEnvironment.getArgument("id");
return new User(id,"springboot+graphql" ,15);
})
).build();
}
@Bean
public GraphQL graphQL(){
return this.graphQL;
}
}
由于没有GraphQL客户端调试软件,我就对controller改造了一下..模拟测试
@GetMapping("/graphql")
@ResponseBody
public Map graphql(){
String query = null;
query = "{user(id:1){id,name}}";
return graphQL.execute(query).toSpecification();
}
启动测试
好的,接下来我们再新增一个查询card的功能
创建Card实体类
package cn.xiechuang.pojo;
public class Card {
private Long id;
private String address;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
编写user.graphql文件
schema {
query: UserQuery
}
type UserQuery {
user(id:Long) : User
card(id:Long) : Card
}
type Card{
id:Long
address:String
}
type User{
id:Long!
name:String
age:Int
}
修改GraphQLProvider类(新增一个dataFetcher)
package cn.xiechuang.graphql;
import cn.xiechuang.pojo.Card;
import cn.xiechuang.pojo.User;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileNotFoundException;
@Component
public class GraphQLProvider {
private GraphQL graphQL;
@PostConstruct
public void init() throws FileNotFoundException {
File file = ResourceUtils.getFile("classpath:user.graphqls");
GraphQLSchema graphQLSchema = createGraphQLSchema(file);
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
}
public GraphQLSchema createGraphQLSchema(File file){
SchemaGenerator schemaGenerator = new SchemaGenerator();
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry typeRegistry = schemaParser.parse(file);
return schemaGenerator.makeExecutableSchema(typeRegistry, buildResolver());
}
public RuntimeWiring buildResolver(){
return RuntimeWiring.newRuntimeWiring()
.type("UserQuery",builder ->
builder.dataFetcher("user",
dataFetchingEnvironment -> {
Long id = dataFetchingEnvironment.getArgument("id");
return new User(id,"springboot+graphql" ,15);
}).dataFetcher("card",
dataFetchingEnvironment ->{
Long id = dataFetchingEnvironment.getArgument("id");
return new Card(id, "futian");
} )
).build();
}
@Bean
public GraphQL graphQL(){
return this.graphQL;
}
}
改写controller测试
@GetMapping("/graphql")
@ResponseBody
public Map graphql(){
String query = null;
// query = "{user(id:1){id,name}}";
query = "{card(id:1){id,address}}";
return graphQL.execute(query).toSpecification();
}
当业务开始复杂的时候,每增加一类查询,就要增加一个dataFetcher,这会显得provider类非常的臃肿,显然是不合适的...优化
package cn.xiechuang.graphql;
import graphql.schema.DataFetchingEnvironment;
public interface MyDataFetcher {
// 查询名称
String fieldName();
/***
* 具体实现数据查询的逻辑**
* @param environment
* * @return
* */
Object dataFetcher(DataFetchingEnvironment environment);
}
package cn.xiechuang.graphql;
import cn.xiechuang.pojo.Card;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.stereotype.Component;
//托管给spring
@Component
public class CardDataFatcher implements MyDataFetcher {
@Override
public String fieldName() {
return "card";
}
@Override
public Object dataFetcher(DataFetchingEnvironment environment) {
Long id = environment.getArgument("id");
return new Card(id, "futian");
}
}
更改provider
package cn.xiechuang.graphql;
import cn.xiechuang.pojo.Card;
import cn.xiechuang.pojo.User;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
@Component
public class GraphQLProvider {
private GraphQL graphQL;
@Autowired
List fetchers;//依赖注入实现类
@PostConstruct
public void init() throws FileNotFoundException {
File file = ResourceUtils.getFile("classpath:user.graphqls");
GraphQLSchema graphQLSchema = createGraphQLSchema(file);
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
}
public GraphQLSchema createGraphQLSchema(File file){
SchemaGenerator schemaGenerator = new SchemaGenerator();
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry typeRegistry = schemaParser.parse(file);
return schemaGenerator.makeExecutableSchema(typeRegistry, buildResolver());
}
public RuntimeWiring buildResolver(){
return RuntimeWiring.newRuntimeWiring()
.type("UserQuery",builder ->{
for (MyDataFetcher fetcher : fetchers) {
builder.dataFetcher(fetcher.fieldName(),
dataFetchingEnvironment ->{
return fetcher.dataFetcher(dataFetchingEnvironment);
}
);
}
return builder;
}
// builder.dataFetcher("user",
// dataFetchingEnvironment -> {
// Long id = dataFetchingEnvironment.getArgument("id");
// return new User(id,"springboot+graphql" ,15);
// }).dataFetcher("card",
// dataFetchingEnvironment ->{
// Long id = dataFetchingEnvironment.getArgument("id");
// return new Card(id, "futian");
// })
).build();
}
@Bean
public GraphQL graphQL(){
return this.graphQL;
}
}
测试