web-dev-qa-db-ja.com

GraphQL-JavaからHashMap <String、Object>を返す

私はいくつかのバリアントを試しましたが、GraphQLでマップを返すことができませんでした。したがって、次の2つのオブジェクトがあります。

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

誰かがこれを達成する方法を教えてください.

どうもありがとう!

7
Simple-Solution

念のため-マップオブジェクトを常に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文字列と同様に、顧客と操作できます。

0
Max

ご存じのとおり、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に 拡張スカラー のプロジェクトが追加されました。 ObjectScalar (別名 JsonScalar )実装です。

これで、Map<String, Object>などのタイプを表す場合は、上からのキーと値のペアのアプローチを使用して、値のタイプのみをJSONスカラーにするか、マップ全体を表すことができます。 JSONスカラーとして。

実際のところ、anyマップ(まあ、どんなタイプでも、実際には役に立ちません)をJSONスカラーとして表すことができます。

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

scalar ObjectScalar

利点として、動的構造の形状を正確に維持できるようになりました。欠点は、スカラーであるため、サブ選択を行うことは不可能であり、事前に内部が何であるかを知らずに、すべてをフェッチすることはできません。

6
kaqqao

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!]!
}
2
Bless