Netflix Domain Graph Service(DGS) 是在Netflix内部创建的一个新的开放源代码框架,该框架简化并帮助了使用GraphQL 实现Spring Boot 应用程序。
GraphQL(一)基础介绍及应用示例
shcema
与创建关系数据库的表结构一样,我们将对GraphQL 进行相同的操作,即创建schema 。我们创建的必须位于以下路径/src/main/resources/schema 中,并且在此路径中,Netflix DGS 将负责加载模式。
对于每个模式,我们创建了一个扩展名为graphqls的不同文件。其中有一个QueryResolver 类型,它将具有两个不同的搜索,以及一个MutationResolver 以便能够在数据库中创建对象。 创建3个不同的方案,帐户,用户和银行:
type QueryResolver {
users: [User]
user(id: ID!): User!
}
type MutationResolver {
createUser(user: UserInput!): User
}
input UserInput {
firstName: String!
lastName: String!
address: String!
country: String!
city: String!
age: Int
}
type User {
id: ID!
firstName: String!
lastName: String!
address: String!
country: String!
city: String!
age: Int!
bank: Bank
accounts: [Account]
}
schema {
query: QueryResolver
mutation: MutationResolver
}
实体类
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class UserInput {
private String firstName;
private String lastName;
private int age;
private String address;
private String country;
private String city;
}
定义好schema ,并创建好对应的实体类,Netflix DGS 将负责加载模式。结合下述的DataFetcher 即可将对象的字段绑定,执行相应的逻辑
DataFetcher
DataFetcher 在GraphQL Java 服务器中是一个非常重要的概念,在执行查询时,通过Datafetcher 获取一个字段的数据。也就是说我们需要为query 或mutation 中定义的方法,以及对定义的对象中的字段绑定一个DataFetcher 实现,这样在GraphQL执行语法后才能通过绑定的DataFetcher 执行相应的逻辑。
Netflix 已经创建了它的基于注释的DGS 框架,该框架由Spring Boot 支持,能简化DataFetcher的使用。下面为DGS 框架的基本注释:
@DgsComponent :此注释负责指示类将要执行查询,DataFetcher 类应在定义中带有此注释。@DgsData :每个带有逻辑以执行查询的方法都必须使用@DgsData 进行注释。我们将在其中添加父类型的位置,这是架构的类型以及在架构中定义的字段。@InputArgument :用于定义在查询中作为参数传递的参数。@DgsQuery :parentType 为Query 时@DgsData 的缩写。@DgsMutation :parentType 为Mutation 时@DgsData 的缩写。
使用DGS 能够通过实现DgsCustomContextBuilder 类来创建自己的上下文。可以使用它来记录或存储状态,或保存一些通过DataFetchingEnvironment 类访问的信息。
在示例类UserQuery中,可以看到DataFetchingEnvironment 的用法
@DgsComponent
@RequiredArgsConstructor
public class UserQuery {
private final UserRepository userRepository;
private final CustomContextBuilder contextBuilder;
@DgsData(parentType = "QueryResolver", field = "users")
public Iterable<User> findAll(DgsDataFetchingEnvironment dfe) {
var users = (List<User>) userRepository.findAll();
contextBuilder.customContext(users, null, null).build();
return users;
}
@DgsData(parentType = "QueryResolver", field = "user")
public User findById(@InputArgument("id") String id, DataFetchingEnvironment dfe) {
CustomContext customContext = DgsContext.getCustomContext(dfe);
var users = customContext.getUsers();
if (null != users) {
var user = users.stream().filter(u -> u.getId().equals(UUID.fromString(id))).findFirst();
return user.orElseGet(() -> userRepository.findById(UUID.fromString(id)).orElseThrow(DgsEntityNotFoundException::new));
} else {
return userRepository.findById(UUID.fromString(id)).orElseThrow(DgsEntityNotFoundException::new);
}
}
}
Apollo Federation
Apollo Federation将GraphQL API 组合成一个统一的超图(supergraph)
在联合架构中,您的各个 GraphQL API 被称为subgraphs ,它们被组合成一个supergraph 。通过查询您的超图,客户端可以同时查询您的所有子图:
网关充当您的超图的公共访问点。它接收传入的1GraphQL1操作并智能地将它们分布在您的子图中。对于客户端来说,这看起来与查询任何其他GraphQL 服务器完全相同——不需要特殊配置。 即Apollo Federation 可以做到,通过网关将多个graphql对外输出成一个,客户端即可通过一次请求获取多个业务线的所有Graphql
Apollo Federation 目前不支持GraphQL 订阅操作
优化思路
- 优化关注数量获取。如果已经拿过关注列表,就从关注列表中获取关注总数
参考资料:
- GraphQL
- graphql-java-tools
- GraphQL Java从入门到实践
- DGS框架
- Spring Boot和Netflix DGS的GraphQL源码案例
- Apollo Federation
|