GraphQL 是由 Facebook 创造的用于描述复杂数据模型的一种查询语言。这里查询语言所指的并不是常规意义上的类似 sql 语句的查询语言,而是一种用于前后端数据查询方式的规范。

字段(Fields)在GraphQL的查询中,请求结构中包含了所预期结果的结构,这个就是字段。并且响应的结构和请求结构基本一致,这是GraphQL的一个特性,这样就可以让请求发起者很清楚的知道自己想要什么。

参数(Arguments)在查询数据时,离不开传递参数,在GraphQL的查询中,也是可以传递参数的,语法:(参数名:参数值)

别名(Aliases)如果一次查询多个相同对象,但是值不同,这个时候就需要起别名了,否则json的语法就不能通过了

片段(Fragments)
查询对的属相如果相同,可以采用片段的方式进行简化定义

Schema 是用于定义数据结构的,比如说,User对象中有哪些属性,对象与对象之间是什么关系等。
Schema定义结构
schema { #定义查询
query: UserQuery
}
type UserQuery { #定义查询的类型
user(id:ID) : User #指定对象以及参数类型
}
type User { #定义对象
id:ID! # !表示该属性是非空项
name:String
age:Int
}
标量类型(Scalar Types)
GraphQL规范中,默认定义了5种类型:
Int :有符号 32 位整数。
Float :有符号双精度浮点值。
String :UTF‐8 字符序列。
Boolean : true 或者 false 。
ID :ID 标量类型表示一个唯一标识符,通常用以重新获取对象或者作为缓存中的键。
规范中定义的这5种类型,显然是不能满足需求的,所以在各种语言实现中,都有对类型进行了扩充,也就是GraphQL支持自定义类型,比如在graphql-java实现中增加了:Long、Byte等
枚举类型
枚举类型是一种特殊的标量,它限制在一个特殊的可选值集合内
enum Episode { #定义枚举
NEWHOPE
EMPIRE
JEDI
}
type Human {
id: ID!
name: String!
appearsIn: [Episode]! #使用枚举类型
homePlanet: String
}
接口(interface)
跟许多类型系统一样,GraphQL 支持接口。一个接口是一个抽象类型,它包含某些字段,而对象类型必须包含这些字段,才能算实现了这个接口。例如,你可以用一个 Character 接口用以表示《星球大战》三部曲中的任何角色:
interface Character { #定义接口
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
#实现接口
type Human implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
starships: [Starship]
totalCredits: Int
}
type Droid implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
primaryFunction: String
}
通过前面的讲解,我们对GraphQL有了解,官方只是定义了规范并没有做实现,就需要有第三方来进行实现了,关于GraphQL的java实现有几种,我们选择使用官方推荐的实现:graphql-java,我们通过该实现就可以编写GraphQL的服务端了。
创建工程工程名:itcast-graphql-java-2
导入依赖:
<dependency>
<groupId>com.graphql-javagroupId>
<artifactId>graphql-javaartifactId>
<version>11.0version>
dependency>
说明:graphql-java包并没有发布到maven中央仓库,需要配置第三方仓库才能使用。
在setting.xml文件里进行配置:
<profile>
<id>bintrayid>
<repositories>
<repository>
<id>bintrayid>
<url>http://dl.bintray.com/andimarek/graphql-javaurl>
<releases>
<enabled>trueenabled>
releases>
<snapshots>
<enabled>falseenabled>
snapshots>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
<id>bintrayid>
<url>http://dl.bintray.com/andimarek/graphql-javaurl>
<releases>
<enabled>trueenabled>
releases>
<snapshots>
<enabled>falseenabled>
snapshots>
pluginRepository>
pluginRepositories>
profile>
<activeProfiles>
<activeProfile>bintrayactiveProfile>
activeProfiles>
创建User对象
package cn.itcast.graphql.vo;
public class User {
private Long id;
private String name;
private Integer age;
private Card card;
public User() {
}
public User(Long id, String name, Integer age, Card card) {
this.id = id;
this.name = name;
this.age = age;
this.card = card;
}
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;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
}
编写查询User对象实现
schema {
query: UserQuery
}
type UserQuery {
user(id:Long) : User
}
type User {
id:Long!
name:String
age:Int
card:Card
}
type Card{
cardNumber:String
userId:Long
}
Java实现:
package cn.itcast.graphql.demo;
import cn.itcast.graphql.vo.User;
import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;
import static graphql.Scalars.*;
import static graphql.schema.GraphQLArgument.newArgument;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLObjectType.newObject;
public class GraphQLDemo {
public static void main(String[] args) {
/**
* type User { #定义对象}
*/
GraphQLObjectType userObjectType = newObject()
.name("User")
.field(newFieldDefinition().name("id").type(GraphQLLong))
.field(newFieldDefinition().name("name").type(GraphQLString))
.field(newFieldDefinition().name("age").type(GraphQLInt))
.build();
/**
* user : User #指定对象以及参数类型
*/
GraphQLFieldDefinition userFieldDefinition = newFieldDefinition()
.name("user")
.type(userObjectType)
.argument(newArgument().name("id").type(GraphQLLong).build())
.dataFetcher(environment -> {
Long id = environment.getArgument("id");
// 查询数据库了
// TODO 先模式实现
return new User(id, "张三:"+id, 20+id.intValue(), null);
})
// .dataFetcher(new StaticDataFetcher(new User(1L, "张三", 20)))
.build();
/**
* type UserQuery { #定义查询的类型}
*/
GraphQLObjectType userQueryObjectType = newObject()
.name("UserQuery")
.field(userFieldDefinition)
.build();
/**
* schema { #定义查询 }
*/
GraphQLSchema graphQLSchema = GraphQLSchema.newSchema().query(userQueryObjectType).build();
GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();
String query = "{user(id:100){id,name}}";
ExecutionResult result = graphQL.execute(query);
System.out.println("query:" + query);
// System.out.println(result.getErrors());
// System.out.println(result.getData());
System.out.println(result.toSpecification());
}
}
运行结果:
query:{user(id:100){id,name}}
{data={user={id=100, name=张三:100}}}

如果运行错误提示:Error:(36, 42) java: -source 1.5 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)
那原因就是在用maven编译项目是由于项目中用了jdk 1.8, 编译是报错 -source 1.5 中不支持 lambda 表达式。在pom.xml中添加如下代码,使用支持JDK1.8的maven插件
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.2version>
<configuration>
<source>1.8source>
<target>1.8target>
configuration>
plugin>
plugins>
build>

graphql-java 提供了两种不同的方式来定义模式:以编程方式作为Java代码或通过特殊的graphql dsl(称为SDL)。
在resources目录下创建user.graphqls文件:
schema {
query: UserQuery
}
type UserQuery {
user(id:Long) : User
}
type User {
id:Long!
name:String
age:Int
card:Card
}
type Card{
cardNumber:String
userId:Long
}
安装GraphQL插件:

构建schema
package cn.itcast.graphql.demo;
import cn.itcast.graphql.vo.Card;
import cn.itcast.graphql.vo.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;
import java.io.IOException;
public class GraphQLSDLDemo {
public static void main(String[] args) throws IOException {
// 读取GraphQL文件,进行解析
String fileName = "user.graphqls";
String fileContent = IOUtils.toString(GraphQLSDLDemo.class.getClassLoader().getResource(fileName), "UTF-8");
TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(fileContent);
// 解决的是数据的查询
RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring()
.type("UserQuery", builder ->
builder.dataFetcher("user", environment -> {
Long id = environment.getArgument("id");
Card card = new Card("123456789", id);
return new User(id, "张三:" + id, 20 + id.intValue(), card);
})
)
.build();
// 生成Schema
GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeRegistry, wiring);
// 根据Schema对象生成GraphQL对象
GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();
String query = "{user(id:100){id,name,age,card{cardNumber}}}";
ExecutionResult result = graphQL.execute(query);
System.out.println("query:" + query);
System.out.println(result.toSpecification());
}
}

运行结果

链接:https://pan.baidu.com/s/14Zyl54BbYjWwQdIzwuzNpg?pwd=16kf
提取码:16kf
–来自百度网盘超级会员V3的分享