GraphQL + Java - 如何过滤子字段?

时间:2016-10-26 07:36:45

标签: java annotations graphql graphql-java

我在我的Spring应用程序中使用graphql-javagraphql-java-annotationsspring-graphql-common似乎非常有限,看起来它不再被维护了),而且我正在努力处理子字段。

我想要使用GraphQL访问两个类AB,这里是:

class A {
    @GraphQLField
    Integer id;
    @GraphQLField
    String name;
    @GraphQLField
    List<B> listOfB;
}

class B {
    @GraphQLField
    Integer id;
    @GraphQLField
    String code;
}

我可以使用以下架构成功查询A中的所有字段以及B中的字段:

@Component
public class Schema
{
    public GraphQLObjectType aType;
    public GraphQLSchema aSchema;
    public GraphQLObjectType queryType;

    @Autowired
    public Schema(DataFetcher dataFetcher) throws IllegalAccessException, InstantiationException, NoSuchMethodException
    {
        aType = GraphQLAnnotations.object(A.class);

        queryType =
                GraphQLObjectType
                .newObject()
                    .name("QueryType")
                    .field(GraphQLFieldDefinition.newFieldDefinition()
                        .name("a")
                        .type(aType)
                        .argument(GraphQLArgument.newArgument()
                                .name("id")
                                .type(new GraphQLNonNull(Scalars.GraphQLInt))
                                .build())
                        .dataFetcher(dataFetcher)
                        .build())
                    .build();

        aSchema = GraphQLSchema.newSchema()
                .query(queryType)
                .build();
    }
}

我可以使用以下请求成功过滤a

{
    a(id:5)
    {
        id,
        name,
        listOfB
        {
            code
        }
    }
}

但是,当我尝试过滤listOfB时,例如使用take来仅选择X记录时,我会收到错误Validation error of type UnknownArgument: Unknown argument take

{
    a(id:5)
    {
        id,
        name,
        listOfB(take:3)
        {
            code
        }
    }
}

我理解错误的含义,因为我没有为listOfB上的A字段声明任何可能的参数,但我不知道如何使用{{1} }}

我使用graphql-java-annotations课程中的以下代码为DataFetcher tho添加了特定的listOfB

A

当我检索@GraphQLDataFetcher(BDataFetcher.class) private List<B> listOfB; 时确实被调用了。

在使用listOfB时,您是否知道如何为字段添加参数?如果没有,是否有任何解决方法?

定义没有注释的模式并使用graphql-java-annotations的“经典”方式不是一个选项,因为我的模式非常庞大:/

谢谢:)

2 个答案:

答案 0 :(得分:1)

这不是我最终使用的解决方案,因为它不适合我的设计,但这是你可以做的:

public class MyClass
{
    @GraphQLField
    private Integer id;
    private List<String> items;

    @GraphQLField
    public List<String> items(DataFetchingEnvironment environment, @GraphQLName("take") Integer take, @GraphQLName("after") Integer after)
    {
        List<String> items = ((MyClass) environment.getSource()).getItems();

        Integer fromIndex = 0;
        Integer toIndex = items.size();
        if (after != null)
            fromIndex = after + 1;
        if (take != null)
            toIndex = fromIndex + take;

        return items.subList(fromIndex, toIndex);
    }
}

这很糟糕,因为您没有使用DataFetcher,因此您的代码将被复制/粘贴到任何地方,但它仍然有效。

但是我找到了一种方法来使用DataFetcher,它说它很奇怪,我猜它不是对图书馆的正确使用,但谁知道:

public class MyClass
{
    @GraphQLField
    private Integer id;
    private List<String> items;

    @GraphQLField
    @GraphQLDataFetcher(MyClassDataFetcher.class)
    public List<String> items(DataFetchingEnvironment environment, @GraphQLName("take") Integer take, @GraphQLName("after") Integer after)
    {
        return null;
    }

}

这会使takeafter中的参数成为DataFetchingEnvironment方法中的MyClassDataFetcher.get(),因此您有一个空方法未被调用,但参数是仍然传递给您的DataFetcher

同样,它并不理想,因为我怀疑它是如何使用的,但它是使用DataFetcher参数的唯一方法我很清楚。

现在,我没有使用这两个解决方案中的任何一个,我最终完全放弃了graphql-annotations并使用自定义注释开发了我自己的解决方案,这些注释允许我自动构建模式(赢得&#39;公开发布,抱歉)。

我建议不要使用graphql-annotations,直到他们为所有用例提供适当的文档。

答案 1 :(得分:1)

我强烈建议你再看一下这个库,因为它现在又回来了 保持,自述非常清楚。

至于你的问题: 你应该让你像这样listOfB

@GraphQLField
@GraphQLDataFetcher(ListOfBFetcher.class)
List<B> listOfB(int take){return null};

在dataFetcher中,您可以从take变量中获取environment参数(通过enviroment.getArgument("take")

您还可以通过执行以下操作使方法成为dataFetcher:

@GraphQLField
List<B> listOfB(int take, DataFetchingEnvironment environment){
    //return the list of B
  };