Sim*_*ion 6 java graphql graphql-java
我尝试了几种变体,没有运气在GraphQL中返回地图。所以我有以下两个对象:
public class Customer {
private String name, age;
// getters & setters
}
public class Person {
private String type;
private Map<String, Customer> customers;
// getters & setters
}
Run Code Online (Sandbox Code Playgroud)
我的架构如下所示:
type Customer {
name: String!
age: String!
}
type Person {
type: String!
customers: [Customer!] // Here I tried all combination but had no luck, is there a Map type support for GQL?
}
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我如何实现这一点,以便GraphQL神奇地处理此问题或替代方法。
非常感谢!
正如您自己指出的那样,GraphQL中没有地图类型,主要是因为地图基本上是无类型的数据(或具有动态结构的数据),因此不能很好地转换为GraphQL期望的静态类型。不过,您还有一些选择。
1)您可以更改值类型,使其包含键,然后放弃在地图上使用列表。这是您自己回答的方法。由于您已经举例说明,因此在此不做详细说明。
2)只要键和值Java类型是已知的(而不是例如Object),您就可以将映射视为键-值对的列表。您可以创建一个类型来表示该对:
type Person {
type: String!
customers: [CustomerEntry!]
}
type CustomerEntry {
key: String!
value: Customer!
}
Run Code Online (Sandbox Code Playgroud)
不利的一面是,您现在遇到了更难看的查询:
{
person {
type
customers {
key
value {
name
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
从好的方面来说,您可以保持类型安全和(主要是)语义。可以继续嵌套此方法以例如表示Map<String, Map<Long, Customer>>。
3)如果您曾经有一个完全未知的类型,即Object,唯一的选择是将其视为复杂的标量。在JavaScript中,这种方法称为JSON标量,因为它归结为将任意JSON结构填充到其中并将其视为标量。可以用Java实现相同的方法。graphql-java现在有一个用于扩展标量的项目。这是他们的ObjectScalar(别名为JsonScalar)实现。
现在,如果要表示类型,例如Map<String, Object>,您可以选择使用上方的键值对方法来表示它,只有值类型为JSON标量,或者可以将整个地图表示为JSON标量。
实际上,您可以决定将任何地图(确实,任何类型,但这都没有用)表示为JSON标量。
type MapEntry {
key: String!
value: [ObjectScalar!]
}
scalar ObjectScalar
Run Code Online (Sandbox Code Playgroud)
从好的方面来说,您现在可以精确地保留任何动态结构的形状。不利的一面是,由于它是一个标量,因此无法进行子选择,并且您在不事先了解内部内容的情况下就无法获取所有内容。
以防万一 - 您始终可以将地图对象表示为 JSON 字符串(在我的情况下它很有帮助)。
public class Person {
private String type;
private Map<String, Customer> customers;
// getters & setters
}
Run Code Online (Sandbox Code Playgroud)
将会
type Person {
type: String!
customers: String!
}
Run Code Online (Sandbox Code Playgroud)
之后不要忘记添加数据获取器以将其转换为 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);
}
};
}
Run Code Online (Sandbox Code Playgroud)
它会返回:
"person": {
"type": "2",
"customers": "{\"VIP\":{\"name\":\"John\",\"age\":\"19\"},\"Platinum VIP\":{\"name\":\"Peter\",\"age\":\"65\"}}"
}
Run Code Online (Sandbox Code Playgroud)
之后,您可以像在客户端中使用典型的 JSON 字符串一样与客户进行操作。
| 归档时间: |
|
| 查看次数: |
6362 次 |
| 最近记录: |