springboot 整合GraphQL-java

这里就不再介绍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类非常的臃肿,显然是不合适的...优化

改进思路:
 
 
1. 编写接口
 
 
2. 所有实现查询的逻辑都实现该接口
 
 
3. GraphQLProvider 中使用该接口的实现类进行处理
 
 
4. 以后需要新增查询逻辑只需要增加实现类即可
 
 
创建接口
 
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;
    }
}

测试

 

 
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值