GraphQL

提供API灵活定制查询

Rest基于文档思路,考虑到多端兼容

  • 返回资源全部字段,无法定制返回范围
  • 关联关系需要客户端发起多次请求自行关联

GraphQL


GraphQL使API具有动态性,查询时携带查询模板,精准定位所需对象和字段
示例展示三个功能:定位一本书,返回部分属性,进行作者关联

1
2
3
4
5
6
7
8
9
10
11
{
bookById(id: "book-1"){
id
name
pageCount
author {
firstName
lastName
}
}
}

GraphQL Schema,通过SDL(Schema Definition Language)定义资源,表示资源有哪些字段,都是什么类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type Query {
bookById(id: ID): Book
}

type Book {
id: ID
name: String
pageCount: Int
author: Author
}

type Author {
id: ID
firstName: String
lastName: String
}

Graphql-Java


不包含通信逻辑,只关注如何解析查询和获取结果
两大组件:类型定义元数据和数据获取器,大体流程是

1
2
3
Schema file   ---parse---->   TypeDefinitionRegistry  \
| ----make---> GraphQLSchema ---build---> GraphQL
Data fetchers --register--> RuntimeWiring /

每个字段都应该指定DataFetcher,默认PropertyDataFetcher

DataFetcher.java
1
2
3
public interface DataFetcher<T> {
T get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception;
}

解析流程是自顶向下,每个被查询的字段调用DataFetcher获取结果,当前字段可以访问环境得到进一步查询所需信息,逐级解析

DataFetchingEnvironment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface DataFetchingEnvironment {
//上一级对象
<T> T getSource();
//客户端查询时传过来的参数
Map<String, Object> getArguments();
//服务端进行查询时传入的全局额外信息
<T> T getContext();
//上一级产出的额外信息
<T> T getLocalContext();
//根对象
<T> T getRoot();
//...
}

Graphql-Playground


https://github.com/prisma-labs/graphql-playground
测试工具