在 GraphQL 中过滤无模式 json 对象
Filter schema-less json object in GraphQL
我有一个数据 JSON 对象,它有几个动态字段,因此我无法在 Graphql 中定义模式,而是使用标量将其定义为 Json。我的要求是使用数据 json 对象过滤字段。下面显示了一个示例用例
query.graphqls
scalar Locale
scalar JSON
type Query {
details: Details!
}
type Details {
locale: Locale!
name: String!
data: JSON!
}
Details.java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Details {
private Locale locale;
private String name;
private List<?> data;
}
ScalarTypeConfig.java
@Configuration
public class ScalarTypeConfig {
@Bean
public GraphQLScalarType locale() {
return ExtendedScalars.Locale;
}
@Bean
public GraphQLScalarType json() {
return ExtendedScalars.Json;
}
}
SampleController.java
@Component
public class SampleController implements GraphQLQueryResolver {
public Details getDetails() {
Details details = new Details();
details.setLocale(Locale.ENGLISH);
details.setName("Manu");
List<Map<String, Integer>> allContents = new ArrayList<>();
Map<String, Integer> contents = new HashMap<>();
contents.put("amount", 112);
contents.put("totalPrice", 333);
allContents.add(contents);
contents = new HashMap<>();
contents.put("amount", 222);
contents.put("totalPrice", 444);
allContents.add(contents);
details.setData(allContents);
return details;
}
}
现在,当我通过以下查询时,我得到了输出
{
details {
name
locale
data
}
}
输出
{
"data": {
"details": {
"name": "Manu",
"locale": "en",
"data": [
{
"amount": 112,
"totalPrice": 333
},
{
"amount": 222,
"totalPrice": 444
}
]
}
}
}
必需的用例
但我的要求是动态只从数据对象中获取指定的字段。例如
{
details {
name
locale
data {
amount
}
}
应该 return 结果如下所示,只有 amount
细节而不显示 totalPrice
预期输出
{
"data": {
"details": {
"name": "Manu",
"locale": "en",
"data": [
{
"amount": 112
},
{
"amount": 222
}
]
}
}
}
有人可以告诉我是否有办法做到这一点。 graphQL 是否支持这种用例
不可能使用标量 json 并期望 graphql 解释它的任何内容。
但是,您可以使用一种巧妙的方法,通过其他方式定义您想要的数据字段:
{
details (dataFields: {
amount: true
}) {
name
locale
data
}
}
你应该定义一个dataFields
参数,类型可以是简单的JSON然后你在Java中解析它并包含或不包含基于[=24=的字段].
在任何情况下都不可能有 GraphQL 可以解析的 JSON。
如果可能,您应该考虑为 data
创建一个合适的类型,而不是原始 JSON。
我有一个数据 JSON 对象,它有几个动态字段,因此我无法在 Graphql 中定义模式,而是使用标量将其定义为 Json。我的要求是使用数据 json 对象过滤字段。下面显示了一个示例用例
query.graphqls
scalar Locale
scalar JSON
type Query {
details: Details!
}
type Details {
locale: Locale!
name: String!
data: JSON!
}
Details.java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Details {
private Locale locale;
private String name;
private List<?> data;
}
ScalarTypeConfig.java
@Configuration
public class ScalarTypeConfig {
@Bean
public GraphQLScalarType locale() {
return ExtendedScalars.Locale;
}
@Bean
public GraphQLScalarType json() {
return ExtendedScalars.Json;
}
}
SampleController.java
@Component
public class SampleController implements GraphQLQueryResolver {
public Details getDetails() {
Details details = new Details();
details.setLocale(Locale.ENGLISH);
details.setName("Manu");
List<Map<String, Integer>> allContents = new ArrayList<>();
Map<String, Integer> contents = new HashMap<>();
contents.put("amount", 112);
contents.put("totalPrice", 333);
allContents.add(contents);
contents = new HashMap<>();
contents.put("amount", 222);
contents.put("totalPrice", 444);
allContents.add(contents);
details.setData(allContents);
return details;
}
}
现在,当我通过以下查询时,我得到了输出
{
details {
name
locale
data
}
}
输出
{
"data": {
"details": {
"name": "Manu",
"locale": "en",
"data": [
{
"amount": 112,
"totalPrice": 333
},
{
"amount": 222,
"totalPrice": 444
}
]
}
}
}
必需的用例
但我的要求是动态只从数据对象中获取指定的字段。例如
{
details {
name
locale
data {
amount
}
}
应该 return 结果如下所示,只有 amount
细节而不显示 totalPrice
预期输出
{
"data": {
"details": {
"name": "Manu",
"locale": "en",
"data": [
{
"amount": 112
},
{
"amount": 222
}
]
}
}
}
有人可以告诉我是否有办法做到这一点。 graphQL 是否支持这种用例
不可能使用标量 json 并期望 graphql 解释它的任何内容。
但是,您可以使用一种巧妙的方法,通过其他方式定义您想要的数据字段:
{
details (dataFields: {
amount: true
}) {
name
locale
data
}
}
你应该定义一个dataFields
参数,类型可以是简单的JSON然后你在Java中解析它并包含或不包含基于[=24=的字段].
在任何情况下都不可能有 GraphQL 可以解析的 JSON。
如果可能,您应该考虑为 data
创建一个合适的类型,而不是原始 JSON。