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

时间:2019-06-21 14:36:26

标签: graphql graphql-java graphql-spqr

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

我遇到的问题如下。

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

第二,当方法返回抽象类时,我似乎只能请求抽象类上的变量。我敢肯定,只要将我的头撞在墙上,这是有可能的。

作为一个简单的例子

public abstract class Animal {
   private String name;
   private int age;

   // Constructor

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

   // Age getter
}


public class Dog extends Animal {
   private String favouriteFood;

   // Constructor

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


public class Database {
    @GraphQLQuery(name = "getanimal")
    public Animal getAnimal(@GraphQLArgument(name = "animalname") String animalname) {
        return database.get(name);
    }
}

所以在我的第一个问题中,我目前正在查询的是什么。 “ {animalname(name:\“ Daisy \”){name age}}“ 这按预期工作正常。如果您想象该类有10个变量,我只希望能够编写以下内容的等效形式而不必查找它们。 “ {node(name:\“ Daisy \”){ALL}}” 这可能吗?

关于我的第二个问题。 以下查询引发错误(“动物”类型的“字段'favouriteFood'未定义”)

"{animalname(name: \"Bones\") {name age favouriteFood}}"

同样(读取https://graphql.org/learn/queries/的内联片段)

"{animalname(name: \"Bones\") {name age ... on Dog{favouriteFood}}}"

引发错误未知类型狗

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

最终,我可以简单地将所有数据序列化为JSON并将其发送回去,从而克服了这两个问题,这摆脱了GraphQL的困扰,我宁愿找到一个替代解决方案。

感谢您的任何回复。 抱歉,如果这些是基本问题。

1 个答案:

答案 0 :(得分:0)

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

抽象类需要包含@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(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();

由于该解决方案需要花一些时间,因此我将与我偶然发现的其他解决方案一起很快开始写博客。

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

我希望这对其他人有帮助。我仍在寻找第一个问题的答案,当我找到一个问题时,将更新此帖子。