我在我的Spring应用程序中使用graphql-java和graphql-java-annotations(spring-graphql-common似乎非常有限,看起来它不再被维护了),而且我正在努力处理子字段。
我想要使用GraphQL访问两个类A
和B
,这里是:
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
的“经典”方式不是一个选项,因为我的模式非常庞大:/
谢谢:)
答案 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;
}
}
这会使take
和after
中的参数成为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
};