2016-10-26 67 views
1

我在我的Spring应用程序中使用了graphql-javagraphql-java-annotationsspring-graphql-common看起来非常有限,看起来它不再被维护),并且我正在努力处理子字段。GraphQL +爪哇 - 如何过滤子域?

我有两个类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,例如用take只选择X的记录,我有错误Validation error of type UnknownArgument: Unknown argument take

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

我明白什么错误意味着,因为我没有宣布AlistOfB领域的任何可能的说法,但我不知道我怎么可以用graphql-java-annotations可能做到这一点。

我已经添加了listOfB寿特定DataFetcher,在A类使用下面的代码:

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

,当我取回listOfB它的确是获取调用。

你有使用graphql-java-annotations时候能怎么加参数字段的任何想法?如果没有,有没有什么解决办法?

定义没有注释的模式和使用的graphql-java“经典”的方式是不是一种选择,因为我的架构是非常巨大的:/

谢谢:)

+0

您是否尝试添加@GraphQLField in listOfB字段与@GraphQLDataFetcher一起?我在这里做一些测试并且工作。 – Sigrist

+0

噢,对不起,它仍然是DataFetcher的'GraphQLField'。但是我仍然遇到同样的错误。我设法通过将'listOfB'定义为方法而不是字段来实现它,但它最终成为了单调乏味的方式,所以我正在编写自定义注释以允许在任何字段上自动过滤,只需添加一个'@ GraphQLAnnotation'注释。 – AntoineB

回答

0

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

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是在MyClassDataFetcher.get()方法DataFetchingEnvironment,使您有没有得到所谓的空方法,但参数仍然传递给你DataFetcher

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

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

我不会推荐使用graphql-annotations,直到他们有适当的所有用例的文档。

0

我强烈建议你再看看这个库,因为它现在保持为 ,并且自述文件非常清晰。

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

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

,并在dataFetcher你可以从environment变量take参数(通过enviroment.getArgument("take")

你可以dataFetcher本身也是这样做的:

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

不错,谢谢你的更新。我不再使用GraphQL工程,尽管现在它不会有用,但如果我再次使用GraphQL,我将确保检查更新:) – AntoineB