我们正在使用graphql-java来构建graphql服务器,但是在遵循Relay规范时遇到了问题。根据中继规范,所有节点都必须可以通过一个查询来检索:node(id: ID)。graphql-java文档显示了对Relay节点接口的支持,但实际实现该接口的文档却相当稀少。我们遇到的确切问题是理解如何为节点查询生成通用查找?Relay Todo示例:https://github.com/graphql-java/todomvc-relay-java展示了一种非常简单的基于代码的方法,只有一个数据获取器,这里的示例不需要“读取”节点“类型”或将请求委托给正确的datafetcher。
schema.graphqls:
type Query {
node(id: ID!): Node
user(id: ID!): User
otherType(id:ID!): OtherType
}
interface Node {
id: ID!
}
type User implements Node {
id: ID!
firstName: String
lastName: String
}
type OtherType implements Node {
id: ID!
description: String
stuff: String
}我们目前正在使用SDL来生成我们的模式(如下所示)
@Bean
private GraphQLSchema schema() {
Url url = Resources.getResource("schema.graphqls");
String sdl = Resources.toString(url, Charsets.UTF_8);
GraphQLSchema graphQLSchema = buildSchema(sdl);
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
return graphQLSchema;
}
private GraphQLSchema buildSchema(String sdl) {
TypeDefinitionRegistry typeRegistry - new SchemaParser().parse(sdl);
RuntimeWiring runtimeWiring = buildWiring();
SchemaGenerator schemaGenerator = new SchemaGenerator();
return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
}
private RuntimeWiring buildWiring(){
return RuntimeWiring.newRuntimeWiring()
.type(newTypeWiring("Query")
.dataFetcher("user", userDispatcher.getUserById()))
.type(newTypeWiring("Query")
.dataFetcher("otherType", otherTypeDispatcher.getOtherTypeById()))
.type(newTypeWiring("Query")
.dataFetcher("node", /*How do we implement this data fetcher? */))
.build()
}假设,我们必须连接一个数据采集器,如上面最后一行所示。然而,这就是文档开始变得模糊的地方。以上内容是否符合继电器规格?不管底层类型是什么(User、OtherType等),我们该如何实现返回对任何单个节点的引用的单节点dataFetcher呢?
发布于 2020-09-04 11:23:31
您是对的,您需要实现一个从node id返回Node的节点数据抓取器。
我将假设您使用的是底层sql数据库: Node可以是任何类型的,这意味着您不能将数据库id用作Node id (因为不同类型的两个节点可能具有相同的数据库id)。您需要构建自己的Node id。
构建此类id的一种简单方法是连接对象类型和对象id。示例:"User:4234“。
正如中继graphql服务器规范所指定的:
我们得到的ID是base64字符串。id被设计为不透明的(唯一应该传递给node上的id参数的是查询系统中某个对象的id的未更改结果),在GraphQL中,base64ing a string是一种很有用的约定,可以提醒查看者该字符串是一个不透明的标识符。
我们需要将节点id编码/解码为基数64。
下面的代码尚未经过测试,但可以让您了解如何继续。
DataFetcher dataFetcher = new DataFetcher() {
@Override
Object get(DataFetchingEnvironment environment) {
Object argument = environment.getArgument("id");
if(argument instanceof String) {
String node = (String) argument;
//TODO decode base 64 nodeId
//TODO split nodeId into String `nodeType` and Long `id`
//TODO retrieve your object of type `nodeType` and id `id`
}
}
}发布于 2021-05-06 03:44:53
模式中的节点接口需要一个TypeResolver和Data Fetcher实现。
即使您提供了一个数据获取器实现并按照AllirionX的建议将其连接起来,您仍然需要为节点接口提供一个解析器,以帮助graphql-java了解它应该解析哪种具体的对象类型。
.type(newTypeWiring("Query").dataFetcher("node", new NodeDataFetcher()))像这样的东西-
.type(newTypeWiring("Node").typeResolver(new TypeResolver() {
@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
return null;
}
}))https://stackoverflow.com/questions/63377943
复制相似问题