首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用graphql-java构建中继GraphQL服务器

用graphql-java构建中继GraphQL服务器
EN

Stack Overflow用户
提问于 2020-08-12 21:48:47
回答 2查看 512关注 0票数 2

我们正在使用graphql-java来构建graphql服务器,但是在遵循Relay规范时遇到了问题。根据中继规范,所有节点都必须可以通过一个查询来检索:node(id: ID)。graphql-java文档显示了对Relay节点接口的支持,但实际实现该接口的文档却相当稀少。我们遇到的确切问题是理解如何为节点查询生成通用查找?Relay Todo示例:https://github.com/graphql-java/todomvc-relay-java展示了一种非常简单的基于代码的方法,只有一个数据获取器,这里的示例不需要“读取”节点“类型”或将请求委托给正确的datafetcher。

schema.graphqls:

代码语言:javascript
复制
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来生成我们的模式(如下所示)

代码语言:javascript
复制
@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呢?

EN

回答 2

Stack Overflow用户

发布于 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。

下面的代码尚未经过测试,但可以让您了解如何继续。

代码语言:javascript
复制
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`
      
    }
  }
}
票数 0
EN

Stack Overflow用户

发布于 2021-05-06 03:44:53

模式中的节点接口需要一个TypeResolver和Data Fetcher实现。

即使您提供了一个数据获取器实现并按照AllirionX的建议将其连接起来,您仍然需要为节点接口提供一个解析器,以帮助graphql-java了解它应该解析哪种具体的对象类型。

代码语言:javascript
复制
.type(newTypeWiring("Query").dataFetcher("node", new NodeDataFetcher()))

像这样的东西-

代码语言:javascript
复制
.type(newTypeWiring("Node").typeResolver(new TypeResolver() {
                @Override
                public GraphQLObjectType getType(TypeResolutionEnvironment env) {
                    return null;
                }
            }))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63377943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档