我尝试了一些变体,没有运气在GraphQL中返回地图。所以我有以下两个对象:
invalid=True
def start():
x=input('Enter the Keyword:')
if ("m" == x) or ("M"==x):
print('Correct!')
elif x!='m' or x!='M':
print('Invalid Input.')
invalid=False
while invalid:
start()
我的架构如下所示:
public class Customer {
private String name, age;
// getters & setters
}
public class Person {
private String type;
private Map<String, Customer> customers;
// getters & setters
}
有人可以告诉我如何实现这一点,以便GraphQL神奇地处理这个或另一种方法。
非常感谢!
答案 0 :(得分:5)
正如您自己所说,GraphQL中没有地图类型,主要是因为地图基本上是无类型数据(或具有动态结构的数据),因此不能很好地转换为GraphQL期望的静态类型。不过,你有几个选择。
1)您可以更改值类型,使其包含密钥,然后放弃地图并使用列表。这是您在自己的答案中采用的方法。我不会在这里详细说明,因为你已经举例说明了它。
2)只要知道了键和值Java类型(而不是Object
),就可以将地图视为键值对列表。您可以创建一个类型来表示该对:
type Person {
type: String!
customers: [CustomerEntry!]
}
type CustomerEntry {
key: String!
value: Customer!
}
在不利方面,你现在有更丑陋的疑问:
{
person {
type
customers {
key
value {
name
}
}
}
}
在好的方面,你保持类型安全和(大部分)语义。可以将这种方法嵌套到例如代表Map<String, Map<Long, Customer>>
。
3)如果您有一个完全未知的类型,即Object
,唯一的选择是将其视为一个复杂的标量。在JavaScript中,这种方法被称为JSON scalar,因为它归结为填充任意JSON结构并将其视为标量。可以用Java实现相同的方法。 graphql-java现在有一个extended scalars的项目。这是他们的ObjectScalar(别名为JsonScalar)实现。
现在,如果您想表示Map<String, Object>
之类的类型,您可以选择使用上面的键值对方法来表示它,只有值类型是JSON标量,或者您可以表示整个地图作为JSON标量。
事实上,你可以决定代表任何地图(嗯,任何类型,但这没用),作为JSON标量。
type MapEntry {
key: String!
value: [ObjectScalar!]
}
scalar ObjectScalar
在好的方面,您现在可以准确地保留任何动态结构的形状。 在缺点方面,因为它是一个标量,所以不可能进行子选择,并且你不知道所有内容,而不知道内部是什么。
答案 1 :(得分:2)
GraphQL中没有地图类型(Discussion on GitHub)。
另一种方法是将customers
作为List
Customer
的<{1}}
public class Person {
private String type;
private List<Customer> customers;
}
并在Customer
类
public class Customer {
private String key; // or another meaningful name
private String name, age;
}
Schema大部分都保持不变。
type Customer {
key: String! // or another meaningful name
name: String!
age: String!
}
type Person {
type: String!
customers: [Customer!]!
}
答案 2 :(得分:0)
以防万一-您始终可以将地图对象表示为JSON字符串(对我而言,这很有用)。
public class Person {
private String type;
private Map<String, Customer> customers;
// getters & setters
}
将会
type Person {
type: String!
customers: String!
}
此后,别忘了添加数据获取程序以将其转换为JSON。
public DataFetcher<String> fetchCustomers() {
return environment -> {
Person person = environment.getSource();
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(person.getCustomers());
} catch (JsonProcessingException e) {
log.error("There was a problem fetching the person!");
throw new RuntimeException(e);
}
};
}
它将返回:
"person": {
"type": "2",
"customers": "{\"VIP\":{\"name\":\"John\",\"age\":\"19\"},\"Platinum VIP\":{\"name\":\"Peter\",\"age\":\"65\"}}"
}
此后,您可以像处理客户端中的典型JSON字符串一样与客户合作。