2

我在我的 Spring 应用程序中使用带有graphql -java-annotations的 graphql-java ( spring-graphql-common似乎非常有限,看起来不再维护),并且我正在努力处理子字段操作。

我有两个类AB我想使用 GraphQL 访问它们,它们是:

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,例如使用 atake仅选择 X 记录时,出现错误Validation error of type UnknownArgument: Unknown argument take

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

我理解错误的含义,因为我没有为listOfB字段声明任何可能的参数 on A,但我不知道如何使用graphql-java-annotations.

我已经添加了一个特定DataFetcherlistOfB,在类中使用以下代码A

@GraphQLDataFetcher(BDataFetcher.class)
private List<B> listOfB;

当我检索时它确实被调用了listOfB

您对使用时如何向字段添加参数有任何想法graphql-java-annotations吗?如果没有,是否有任何解决方法?

定义没有注释的模式并使用“经典”方式graphql-java不是一种选择,因为我的模式真的很大:/

谢谢 :)

4

2 回答 2

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);
    }
}

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

但是我找到了一种使用 a 的方法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;
    }

}

这将使参数成为你的方法take,所以你有一个没有被调用的空方法,但参数仍然传递给你的.afterDataFetchingEnvironmentMyClassDataFetcher.get()DataFetcher

同样,它并不理想,因为我怀疑它是如何被使用的,但这是DataFetcher我知道的使用带有参数的唯一方法。

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

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

于 2016-11-22T09:35:18.980 回答
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
  };
于 2017-11-03T15:52:06.823 回答