graphql java demo_GraphQL实战-第二篇-java实现及分析

GraphQL实战-第二篇-java实现及分析

到这里必须具备的知识储备:对GraphQL有简单的了解,了解Schema的常用类型。

这里用一些demo示例来体验GraphQL的执行过程,这只是借助graphql-java实现的java版本。

首先需要引入graphql-java的依赖

com.graphql-java

graphql-java

15.0

Demo1

第一个demo是官网提供的

import graphql.ExecutionResult;

import graphql.GraphQL;

import graphql.schema.GraphQLSchema;

import graphql.schema.StaticDataFetcher;

import graphql.schema.idl.RuntimeWiring;

import graphql.schema.idl.SchemaGenerator;

import graphql.schema.idl.SchemaParser;

import graphql.schema.idl.TypeDefinitionRegistry;

import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring;

public class HelloWorld {

public static void main(String[] args) {

//定义schema文件,直接写在了代码中,包含一个hello的查询方法

String schema = "type Query{hello: String} schema{query: Query}";

SchemaParser schemaParser = new SchemaParser();

//直接加载schema,初始化GraphQL

TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);

//加载一份服务端数据

RuntimeWiring runtimeWiring = new RuntimeWiring()

.type("Query", builder -> builder.dataFetcher("hello", new StaticDataFetcher("world")))

.build();

SchemaGenerator schemaGenerator = new SchemaGenerator();

GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);

// 构建一个GraphQL实例,执行graphql脚本

GraphQL build = GraphQL.newGraphQL(graphQLSchema).build();

ExecutionResult executionResult = build.execute("{hello}");

System.out.println(executionResult.getData().toString());

// Prints: {hello=world}

}

}

这个demo直接加载了schema的内容,构建Graphql执行脚本。这种方式最接近于实际开发的操作。

Deom2

通过这个demo来看一下一个GraphQL的服务端都做了什么。并对比一下java代码加载GraphQL对象与schema中的GraphQL的联系。

所依赖的对象User

/**

* ClassName: User

* Description:

* date: 2019/6/28 10:38 AM

*

* @author chengluchao

* @since JDK 1.8

*/

@Data

public class User {

private int age;

private long id;

private String name;

private Card card;

public User(int age, long id, String name, Card card) {

this.age = age;

this.id = id;

this.name = name;

this.card = card;

}

public User(int age, long id, String name) {

this.age = age;

this.id = id;

this.name = name;

}

}

/**

* ClassName: Card

* Description:

* date: 2019/6/28 3:25 PM

*

* @author chengluchao

* @since JDK 1.8

*/

@Data

public class Card {

private String cardNumber;

private Long userId;

public Card(String cardNumber, Long userId) {

this.cardNumber = cardNumber;

this.userId = userId;

}

}

接下来是demo

/**

* ClassName: GraphQLDemo

* Description:

* date: 2019/6/28 10:40 AM

*

* @author chengluchao

* @since JDK 1.8

*/

public class GraphQLDemo {

public static void main(String[] args) {

/*

定义GraphQL对象,等同于schema中定义的

type User {

id:ID

age:Int

name:String

}

*/

GraphQLObjectType userObjectType = GraphQLObjectType.newObject()

.name("User")

.field(GraphQLFieldDefinition.newFieldDefinition().name("id").type(Scalars.GraphQLLong))

.field(GraphQLFieldDefinition.newFieldDefinition().name("age").type(Scalars.GraphQLInt))

.field(GraphQLFieldDefinition.newFieldDefinition().name("name").type(Scalars.GraphQLString))

.build();

/*

queryUser : User 指定对象及参数类型

等同于在GraphQL中定义一个无参方法 queryUser,返回值为User

queryUser:User

dataFetcher指定了响应的数据集,这个demo里使用了静态写入的方式

*/

GraphQLFieldDefinition userFileldDefinition = GraphQLFieldDefinition.newFieldDefinition()

.name("queryUser")

.type(userObjectType)

//静态数据

.dataFetcher(new StaticDataFetcher(new User(19, 2, "CLC")))

.build();

/*

type UserQuery 定义查询类型

对应的graphQL为:

type UserQuery {

queryUser:User

}

*/

GraphQLObjectType userQueryObjectType = GraphQLObjectType.newObject()

.name("UserQuery")

.field(userFileldDefinition)

.build();

/*

Schema 定义查询

定义了query的root类型

对应的GraphQL语法为:

schema {

query:UserQuery

}

*/

GraphQLSchema qlSchema = GraphQLSchema.newSchema().query(userQueryObjectType).build();

//构建一个GraphQl对象,执行逻辑都在此处进行

GraphQL graphQL = GraphQL.newGraphQL(qlSchema).build();

//模拟客户端传入查询脚本,方法名queryUser,获取响应值为 id name age

String query = "{queryUser{id name age}}";

// 执行业务操作逻辑,获取返回值

ExecutionResult result = graphQL.execute(query);

System.out.println(result.toSpecification());

}

}

这里对应的sehema应该是这样的:

#对应的User定义如下

schema {

#定义查询

query: UserQuery

}

#定义查询类型

type UserQuery {

#指定对象以及参数类型

queryUser : User

}

#定义对象

type User {

#!表示非空

id: ID!

name:String

age:Int

card:Card

}

type Card {

cardNumber:String

userId:ID

}

可以看出:

schema的结构层级是:schema > UserQuery > User

schema中定义的是操作类型,UserQuery下定义的是操作方法,而User对应的是GraphQL的对象,此对象应该对应于java中一个相同的对象

以上demo实现中有两点是实战中不可取的:

schema的加载方式,应该以读取本地配置的形式加载

dataFetcher的数据加载,demo中是静态写死的方式,实战中应该是动态加载的数据

接下来从这两点改进

demo3

首先在resources目录下创建一个user.graphqls的文件

#对应的User定义如下

schema {

#定义查询

query: UserQuery

}

#定义查询类型

type UserQuery {

#指定对象以及参数类型

queryUser : User

queryUserById(id:ID) : User

}

#定义对象

type User {

#!表示非空

id: ID!

name:String

age:Int

card:Card

}

type Card {

cardNumber:String

userId:ID

}

import clc.bean.Card;

import clc.bean.User;

import graphql.ExecutionResult;

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.apache.commons.io.IOUtils;

/**

* ClassName: GraphQLSDLDemo

* Description:

* date: 2019/6/28 11:19 AM

*

* @author chengluchao

* @since JDK 1.8

*/

public class GraphQLSDLDemo {

public static void main(String[] args) throws Exception {

//读取graphqls文件

String fileName = "user.graphqls";

String fileContent = IOUtils.toString(GraphQLSDLDemo.class.getClassLoader().getResource(fileName), "UTF-8");

//解析文件

TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(fileContent);

RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring()

.type("UserQuery", builder ->

builder.dataFetcher("queryUserById", environment -> {

//解析请求参数,根据业务返回结果

Long id = Long.parseLong(environment.getArgument("id"));

Card card = new Card("123456", id);

return new User(18, id, "user0" + id, card);

})

)

.build();

GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, wiring);

GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();

String query = "{queryUserById(id:15){id,name,age,card{cardNumber,userId}}}";

ExecutionResult result = graphQL.execute(query);

System.out.println("query: " + query);

System.out.println(result.toSpecification());

}

}

从demo升级成实战项目需要做的内容:

schema与java代码分离,可以通过读取文件的形式将schema加载到系统中;

动态处理GraphQL的请求参数,并随之生成对应的响应

可能大家已经发现,入参和出参都需要服务端编码实现解析。

其实graphql-java做的事情是很有限的,主要作用如下:

维护schema的结构

根据GraphQL的脚本需要,过滤响应结果

其他很大一部分的工作都需要自己实现的。

CLC

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值