JavaEE:GraphQL使用

说明:

GraphQL是API规范,实现需要什么数据时就获取什么数据,避免垃圾数据的返回,能整合多个接口的数据一起返回,提高客户端用户体验。

一、查询规范:

请求接口时,用GQL客户端或浏览器GQL插件发送如下"查询字符串格式",接口会返回相应json格式。

1.字段:

查询字符串格式:

{
      user {
             name
      }
}

返回json格式:

{
      “data”: {
            “user”: {
                   “name”: “X先生”
             }
      }
}

2.传参数:

查询字符串格式:

{
      user(id: 1) { //参数: 值
             name
      }
}

返回json格式:

{
      “data”: {
            “user”: {
                   “name”: “X先生”
             }
      }
}

3.别名(有多个相同类型的,要定别名):

查询字符串格式:

{
      别名1: user {
             name
      }
      别名2: user {
             name
      }
}

返回json格式:

{
      “data”: {
            “ 别名1:”: {
                   “name”: “X先生1”
             },
             “ 别名2:”: {
                   “name”: “X先生2”
             }
      }
}

4.片段 :

查询字符串格式:

{
      别名1: user {
             …通用名  //引入通用片段
      }
      别名2: user {
             …通用名  //引入通用片段
      }
}

fragment  通用名 on Character {//通用片段
     name
}

返回json格式:

{
      “data”: {
            “ 别名1:”: {
                   “name”: “X先生1”   //引入通用片段
             },
             “ 别名2:”: {
                   “name”: “X先生2”   //引入通用片段
             }
      }
}

二、类型规范:

1.Schema定义:

schema { //定义一个查询的Schema规范
      query: FindUser  //定义查询类型
}

type FindUser {//定义查询类型
      user(id:ID): User   //指定查询参数类型与返回值类型
}

type User { //定义User对象
      id:ID!  //!规定值不能为空
}

2.变量类型:

Int:有符号 32 位整数类型
Float:有符号双精度浮点类型。
String:UTF‐8 字符串类型。
Boolean : 布尔类型,true 或者 false 。
ID:唯一标识符

3.枚举 :

enum Status { //定义枚举
      ONE  //定义值
      TOW  //定义值
}

使用:

type A {
      b : [Status]!  //使用
}

4.接口:

定义接口:

interface 接口名 {
  name: String
}

实现接口:

type 子类名 implements 接口名 {
  name: String  //必须写上接口中的变量
}

三、使用GraphQL:

IDEA安装JS GraphQL插件。

1.IDEA的settings.xml中添加第三方仓库(idea目录/plugins/maven/lib/maven3/conf/settings.xml):

<!-- graphql -->
<profiles>
    <profile>
        <id>bintray</id>
        <repositories>
            <repository>
                <id>bintray</id>
                <url>http://dl.bintray.com/andimarek/graphql-java</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
        <pluginRepositories>
            <pluginRepository>
                <id>bintray</id>
                <url>http://dl.bintray.com/andimarek/graphql-java</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </pluginRepository>
        </pluginRepositories>
    </profile>
</profiles>
<activeProfiles>
    <activeProfile>bintray</activeProfile>
</activeProfiles>

2.工程pom.xml中导入graphql-java依赖包:

<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-java</artifactId>
    <version>15.0</version>
</dependency>

3.在工程resources下创建user.graphqls,定义Schema:

schema { #定义一个查询的Schema规范
     query: FindUser  #定义一个查询
}
type FindUser { #定义一个查询
     user(userNo: String): User #指定查询参数类型与返回值类型
}
type User { #定义User对象
     userNo: String #定义参数列表
     name: String
}

4.实体类:

//用户实体类
public class User {
    private String userNo; //用户编号
    private String name; //用户名
    public User(String userNo, String name) {
        this.userNo = userNo;
        this.name = name;
    }
    public String getUserNo() {
        return userNo;
    }
    public void setUserNo(String userNo) {
        this.userNo = userNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

5.1.使用Java客户端查询GQL接口获取数据:

//java-GQL客户端
public class GQLClient {
    public static void main(String[] args) {
        //1.读了文件内容
        String content = readFile("user.graphqls");
        //2.得到注册器
        TypeDefinitionRegistry registry = getRegistry(content);
        //3.得到运行时连接
        RuntimeWiring wiring = getWiring();
        //4.得到Schema
        GraphQLSchema schema = getSchema(registry, wiring);
        //5.执行查询
        GraphQL gql = GraphQL.newGraphQL(schema).build();
        Object data = gql.execute("{user(id:1001){id,name}}").getData(); //查询语句,传入GQL格式的字符串
        System.out.println("查询结果为:" + data);
    }
    //1.读取文件内容
    public static String readFile(String fileName) {
        try {
            return streamToStr(GQLClient.class.getClassLoader().getResourceAsStream(fileName));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    //将流转字符串
    public static String streamToStr(InputStream in) {
        if (in != null) {
            try {
                BufferedReader bufRead = new BufferedReader(new InputStreamReader(in));
                StringBuffer sb = new StringBuffer();
                String line;
                while ((line = bufRead.readLine()) != null) {
                    sb.append(line);
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    //2.得到注册器
    public static TypeDefinitionRegistry getRegistry(String fileContent) {
        return new SchemaParser().parse(fileContent);
    }
    //3.得到运行时连接
    public static RuntimeWiring getWiring() {//FindUser为user.graphqls中自定义类型,user为user.graphqls文件名
        return RuntimeWiring.newRuntimeWiring().type("FindUser",
                typeWiring -> typeWiring.dataFetcher("user", environment -> {
                    String userNo = environment.getArgument("userNo"); //获取用户编号
                    return new User(userNo, "X先生");
                })
        ).build();
    }
    //4.得到Schema
    public static GraphQLSchema getSchema(TypeDefinitionRegistry registry, RuntimeWiring wiring) {
        return new SchemaGenerator().makeExecutableSchema(registry, wiring);
    }
}

5.2.与Spring整合部署GQL接口,使用插件请求GQL接口获取数据:

(1)定义通用GQL查询接口:

public interface GQLInterface {
    //查询名称
    String fieldName();
    //由子类实现具体查询
    Object dataFetcher(DataFetchingEnvironment env);
}

(2)实现通用GQL查询接口:

@Component //通用GQL查询接口的实现类之一,会自动注入List<GQLInterface> gqlImplList
public class UserGQLImpl implements GQLInterface {
    @Autowired
    private UserBiz userBiz; //用户相关的增删改查业务类
    @Override
    public String fieldName() {//实现GQL接口,返回实现名称
        return "UserGQL";
    }
    @Override
    public Object dataFetcher(DataFetchingEnvironment environment) {//实现具体查询业务
        String userNo = environment.getArgument("userNo"); //获取请求参数userNo
        return userBiz.query(userNo); //执行真正的查询业务
    }
}

@Service   //用户增删改查业务类
public class UserBiz {
    public User query(String userNo){
        //查询代码...
        return new User("1001", "X先生");
    }
}

(3)创建自动加载的GQL配置类,装载GQL文件进行初始化等操作:

@Component  //Spring-GQL配置类
public class GQLConfig {
    private GraphQL graphQL; //查询对象
    @Bean
    public GraphQL graphQL() {
        return graphQL;
    }
    @Autowired
    private List<GQLInterface> gqlImplList; //实现类列表
    @PostConstruct
    public void init() throws IOException {
        //1.得到File对象
        File file = ResourceUtils.getFile("classpath:user.graphqls");
        //2.得到注册器
        TypeDefinitionRegistry registry = getRegistry(file);
        //3.得到运行时连接
        RuntimeWiring wiring = getWiring();
        //4.得到Schema
        GraphQLSchema schema = getSchema(registry, wiring);
        //5.1 得到GraphQL查询对象
        this.graphQL = GraphQL.newGraphQL(schema).build();
    }
    //2.得到注册器
    public static TypeDefinitionRegistry getRegistry(File file) {
        return new SchemaParser().parse(file);
    }
    //3.得到运行时连接
    private RuntimeWiring getWiring() {//FindUser为user.graphqls中自定义类型,user为user.graphqls文件名
        return RuntimeWiring.newRuntimeWiring().type("FindUser",
                builder -> {
                    for (GQLInterface item : gqlImplList) {//遍历实现类列表,执行每个子类中的查询方法
                        builder.dataFetcher(item.fieldName(), environment -> item.dataFetcher(environment));
                    }
                    return builder;
                }).build();
    }
    //4.得到Schema
    public static GraphQLSchema getSchema(TypeDefinitionRegistry registry, RuntimeWiring wiring) {
        return new SchemaGenerator().makeExecutableSchema(registry, wiring);
    }
}

(4)创建GQL接口请求处理类:

@RequestMapping
@Controller
public class UserController {
    @Autowired
    private GraphQL graphQL; //GQL查询对象
    @GetMapping("/getUserInfo")
    @ResponseBody
    public Map<String, Object> getUserInfo(String query) {
        return graphQL.execute(query).toSpecification(); //执行graphQL查询
    }
}

(5)安装Altair GraphQL Client,请求GQL接口获取数据:

http://www.electronjs.org/apps/altair

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值