GraphQLJava,如何从处理子类的查询和问题中盲目返回与对象关联的所有变量

GraphQLJava,如何从处理子类的查询和问题中盲目返回与对象关联的所有变量,graphql,graphql-java,graphql-spqr,Graphql,Graphql Java,Graphql Spqr,我是GraphQL新手,目前正在使用GraphQL SPQR将GraphQL API实现到已建立的Java代码中,在从分层类提取数据时遇到了几个问题 我遇到的问题如下 首先,我不知道是否有一种简单的方法来获取与返回节点关联的所有数据。如果有的话,这对我的更复杂的类将是最有用的 其次,当一个方法返回一个抽象类时,我似乎只能请求抽象类上的变量。我相信这应该是可能的,我只是把头撞在墙上 举个简单的例子 公共抽象类动物{ 私有字符串名称; 私人互联网; //建造师 @GraphQLQuery(name=

我是GraphQL新手,目前正在使用GraphQL SPQR将GraphQL API实现到已建立的Java代码中,在从分层类提取数据时遇到了几个问题

我遇到的问题如下

首先,我不知道是否有一种简单的方法来获取与返回节点关联的所有数据。如果有的话,这对我的更复杂的类将是最有用的

其次,当一个方法返回一个抽象类时,我似乎只能请求抽象类上的变量。我相信这应该是可能的,我只是把头撞在墙上

举个简单的例子

公共抽象类动物{
私有字符串名称;
私人互联网;
//建造师
@GraphQLQuery(name=“name”)
公共字符串getName(){
返回名称;
}
//增龄剂
}
公家犬{
私人食品;
//建造师
@GraphQLQuery(name=“FavoriteFood”)
公共字符串getFavoriteFood(){
归还喜爱的食物;
}
}
公共类数据库{
@GraphQLQuery(name=“getanimal”)
公共动物getAnimal(@GraphQLArgument(name=“animalname”)字符串animalname){
返回database.get(name);
}
}
所以在我的第一个问题中,我现在质疑的是。 “{animalname(name:\'Daisy\”{name age}” 这工作正常。如果你想象这个类有10个变量,我只想写下下面的等价物,而不需要查找它们。 “{node(名称:\'Daisy\”{ALL}” 这可能吗

关于我的第二个问题。 下面的查询抛出错误('Animal'类型中的'FavoriteFood'字段未定义')

同样(读取的内联片段)

抛出未知类型的错误

这很烦人,因为我有很多子类可以返回,可能需要以不同的方式处理。我想我可以理解为什么会发生这种情况,因为GraphQL不知道真正的类是什么,只知道我返回的超类。但是我想知道是否有办法解决这个问题

最终,虽然我可以通过将所有数据序列化为JSON并发送回JSON来解决这两个问题,但它有点摆脱了GraphQL的问题,我宁愿找到另一个解决方案

谢谢你的回复。
如果这些是基本问题,请道歉。

回答我自己的问题,以帮助其他有此问题的人

抽象类需要包含@GraphQLInterface,如下所示

@GraphQLInterface(name = "Animal ", implementationAutoDiscovery = true)
public abstract class Animal {
   private String name;
   private int age;

   // Constructor

   @GraphQLQuery(name = "name")
   public String getName() {
       return name;
   }

   // Age getter
}
以下代码是经过多次解决后发现的,由SPQR的创建者创建。实际上,在设置模式时,您需要声明接口映射策略。只需将“nodeQuery”变量替换为用于包含“@GraphQLQuery”和“@GraphQLMutation”方法的服务,就可以批量复制下面的代码

final GraphQLSchema schema=new GraphQLSchemaGenerator()
.withInterfaceMappingStrategy(新的InterfaceMappingStrategy(){
@凌驾
公共布尔支持(最终注释类型interbase){
返回interbase.isAnnotationPresent(GraphQLInterface.class);
}
@凌驾
公共集合getInterfaces(最终AnnotatedType类型){
Class clazz=ClassUtils.getRawType(type.getType());
最终设置接口=新HashSet();
做{
最终的AnnotatedType currentType=GenericTypeReflector.getExactSuperType(类型,clazz);
if(支持(当前类型)){
接口。添加(currentType);
}
Arrays.stream(clazz.getInterfaces())
.map(inter->GenericTypeReflector.getExactSuperType(类型,inter))
.filter(this::supports).forEach(interfaces::add);
}while((clazz=clazz.getSuperclass())!=Object.class&&clazz!=null);
返回接口;
}
}).withOperationsFromSingleton(nodeQuery)//注册服务
.generate();//完成;)
graphQL=新的graphQL.Builder(schema.build();
由于这个解决方案需要一些探索,我将很快用我偶然发现的其他解决方案创建一个博客

关于只返回所有结果的查询。这在GraphQL中是不可能的。我可能编写的一种解决方法是使用一个端点返回整个对象的JSON和对象的名称,然后我可以使用ObjectMapper将其转换回来


我希望这能帮助其他人。我仍在寻找我的第一个问题的答案,当我找到答案时,我会更新这篇文章。

回答我自己的问题,以帮助其他有这个问题的人

抽象类需要包含@GraphQLInterface,如下所示

@GraphQLInterface(name = "Animal ", implementationAutoDiscovery = true)
public abstract class Animal {
   private String name;
   private int age;

   // Constructor

   @GraphQLQuery(name = "name")
   public String getName() {
       return name;
   }

   // Age getter
}
以下代码是经过多次解决后发现的,由SPQR的创建者创建。实际上,在设置模式时,您需要声明接口映射策略。只需将“nodeQuery”变量替换为用于包含“@GraphQLQuery”和“@GraphQLMutation”方法的服务,就可以批量复制下面的代码

final GraphQLSchema schema=new GraphQLSchemaGenerator()
.withInterfaceMappingStrategy(新的InterfaceMappingStrategy(){
@凌驾
公共布尔支持(最终注释类型interbase){
返回interbase.isAnnotationPresent(GraphQLInterface.class);
@GraphQLInterface(name = "Animal ", implementationAutoDiscovery = true)
public abstract class Animal {
   private String name;
   private int age;

   // Constructor

   @GraphQLQuery(name = "name")
   public String getName() {
       return name;
   }

   // Age getter
}
final GraphQLSchema schema = new GraphQLSchemaGenerator()
                .withInterfaceMappingStrategy(new InterfaceMappingStrategy() {
                    @Override
                    public boolean supports(final AnnotatedType interfase) {
                        return interfase.isAnnotationPresent(GraphQLInterface.class);
                    }

                    @Override
                    public Collection<AnnotatedType> getInterfaces(final AnnotatedType type) {
                        Class clazz = ClassUtils.getRawType(type.getType());
                        final Set<AnnotatedType> interfaces = new HashSet<>();
                        do {
                            final AnnotatedType currentType = GenericTypeReflector.getExactSuperType(type, clazz);
                            if (supports(currentType)) {
                                interfaces.add(currentType);
                            }
                            Arrays.stream(clazz.getInterfaces())
                                    .map(inter -> GenericTypeReflector.getExactSuperType(type, inter))
                                    .filter(this::supports).forEach(interfaces::add);
                        } while ((clazz = clazz.getSuperclass()) != Object.class && clazz != null);
                        return interfaces;
                    }
                }).withOperationsFromSingleton(nodeQuery)// register the service
                .generate(); // done ;)
        graphQL = new GraphQL.Builder(schema).build();