這裏就不再介紹GraphQL了,有興趣的同學可以看https://blog.csdn.net/qq_40794266/article/details/102961334
導入依賴
<!--spring boot的支持-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<!--springboot的web支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>11.0</version>
</dependency>
<!--io操作工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
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<String,Object> 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<String,Object> 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<String,Object> 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<MyDataFetcher> 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;
}
}
測試