返回 HashMap<String, Object> from GraphQL-Java

2022-09-03 02:19:54

我尝试了几个变体,没有运气在GraphQL中返回一个映射。所以我有以下两个对象:

public class Customer {

    private String name, age;
    // getters & setters
}

public class Person {

   private String type;
   private Map<String, Customer> customers;
   // getters & setters
}

我的架构如下所示:

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?
}

有人可以告诉我如何实现这一点,以便 GraphQL 神奇地处理这个或另一种方法。

非常感谢!


答案 1

正如你自己所指出的,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)如果你有一个完全未知的类型,即,唯一的选择是把它当作一个复杂的标量。在JavaScript中,这种方法被称为JSON标量,因为它归结为填充任意JSON结构并将其视为标量。同样的方法也可以在Java中实现。graphql-java 现在有一个用于扩展标量的项目。这是他们的ObjectScalar(别名为JsonScalar)实现。Object

现在,如果要表示诸如 的类型,则可以选择使用上面的键值对方法表示它,只有值类型是 JSON 标量,或者可以将整个映射表示为 JSON 标量。Map<String, Object>

事实上,你可以决定将任何映射(嗯,真的是任何类型,但这没有用)表示为JSON标量。

type MapEntry {
  key: String!
  value: [ObjectScalar!]
}

scalar ObjectScalar

从好的方面来说,您现在可以精确地保持任何动态结构的形状。不利的一面是,由于它是一个标量,因此不可能进行子选择,并且您无法提前知道其中的内容而无法获取所有内容。


答案 2

GraphQL 中没有映射类型(GitHub 上的讨论)。

另一种方法是将customersListCustomer

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;
}

架构将基本保持不变。

type Customer {
   key: String! // or another meaningful name
   name: String!
   age: String!
}

type Person {
  type: String!
  customers: [Customer!]!
}

推荐