GraphQL + Java - 如何过滤子字段?
GraphQL + Java - How do I filter subfields?
我正在使用 graphql-java with graphql-java-annotations in my Spring application (spring-graphql-common 似乎非常有限,看起来它不再维护了),我正在努力处理子字段操作。
我想使用 GraphQL 访问两个 classes 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
到 select X 条记录,我得到错误 Validation error of type UnknownArgument: Unknown argument take
:
{
a(id:5)
{
id,
name,
listOfB(take:3)
{
code
}
}
}
我明白错误的含义,因为我还没有为 A
上的 listOfB
字段声明任何可能的参数,但我不知道如何使用 graphql-java-annotations
.
我已经为 listOfB
添加了一个特定的 DataFetcher
,使用 class A
中的以下代码:
@GraphQLDataFetcher(BDataFetcher.class)
private List<B> listOfB;
当我检索 listOfB
.
时它确实被调用了
您知道我在使用 graphql-java-annotations
时如何向字段添加参数吗?如果没有,是否有任何解决方法?
在没有注释的情况下定义模式并使用 graphql-java
的 "classic" 方式不是一个选项,因为我的模式真的很大 :/
谢谢:)
这不是我最终使用的解决方案,因为它不符合我的设计,但您可以执行以下操作:
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
所以你的代码将 copy/pasted 无处不在,但它仍然有效。
但我找到了一种使用 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
成为 MyClassDataFetcher.get()
方法中的 DataFetchingEnvironment
,因此您有一个未被调用的空方法,但参数仍然传递给你的 DataFetcher
.
同样,这并不理想,因为我怀疑它的使用方式,但这是使用 DataFetcher
和我知道的参数的唯一方法。
现在,我没有使用这两个解决方案中的任何一个,我最终完全放弃 graphql-annotations
并开发了我自己的带有自定义注释的解决方案,这些注释允许我自动构建模式(不会公开发布,抱歉)。
我不建议使用 graphql-annotations
,除非他们有适用于所有用例的文档。
我强烈建议你再看看这个图书馆,因为它现在又回来了
维护了,readme写的很清楚
关于你的问题:
你应该让你的字段 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
};
我正在使用 graphql-java with graphql-java-annotations in my Spring application (spring-graphql-common 似乎非常有限,看起来它不再维护了),我正在努力处理子字段操作。
我想使用 GraphQL 访问两个 classes 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
到 select X 条记录,我得到错误 Validation error of type UnknownArgument: Unknown argument take
:
{
a(id:5)
{
id,
name,
listOfB(take:3)
{
code
}
}
}
我明白错误的含义,因为我还没有为 A
上的 listOfB
字段声明任何可能的参数,但我不知道如何使用 graphql-java-annotations
.
我已经为 listOfB
添加了一个特定的 DataFetcher
,使用 class A
中的以下代码:
@GraphQLDataFetcher(BDataFetcher.class)
private List<B> listOfB;
当我检索 listOfB
.
您知道我在使用 graphql-java-annotations
时如何向字段添加参数吗?如果没有,是否有任何解决方法?
在没有注释的情况下定义模式并使用 graphql-java
的 "classic" 方式不是一个选项,因为我的模式真的很大 :/
谢谢:)
这不是我最终使用的解决方案,因为它不符合我的设计,但您可以执行以下操作:
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
所以你的代码将 copy/pasted 无处不在,但它仍然有效。
但我找到了一种使用 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
成为 MyClassDataFetcher.get()
方法中的 DataFetchingEnvironment
,因此您有一个未被调用的空方法,但参数仍然传递给你的 DataFetcher
.
同样,这并不理想,因为我怀疑它的使用方式,但这是使用 DataFetcher
和我知道的参数的唯一方法。
现在,我没有使用这两个解决方案中的任何一个,我最终完全放弃 graphql-annotations
并开发了我自己的带有自定义注释的解决方案,这些注释允许我自动构建模式(不会公开发布,抱歉)。
我不建议使用 graphql-annotations
,除非他们有适用于所有用例的文档。
我强烈建议你再看看这个图书馆,因为它现在又回来了 维护了,readme写的很清楚
关于你的问题:
你应该让你的字段 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
};