web-dev-qa-db-ja.com

動的キーを持つオブジェクトのApollo / GraphQLフィールドタイプ

私のgraphqlサーバーが次のデータをJSONとしてフェッチするとします。ここでperson3およびperson5はいくつかのIDです:

"persons": {
  "person3": {
    "id": "person3",
    "name": "Mike"
  },
  "person5": {
    "id": "person5",
    "name": "Lisa"
  }
}

質問:アポロを使用してスキーマタイプ定義を作成する方法

キーperson3およびperson5ここでは、私のクエリに応じて動的に生成されます(つまり、クエリで使用されるarea)。したがって、別の機会にperson1person2person3 戻ってきた。ご覧のように、personsはIterableではないため、以下はapolloで実行したgraphql型定義としては機能しません。

type Person {
  id: String
  name: String
}
type Query {
  persons(area: String): [Person]
}

personsオブジェクトのキーは常に異なる場合があります。

もちろん、1つの解決策は、着信JSONデータを変換してpersonsの配列を使用することですが、そのようにデータを処理する方法はありませんか?

18
Andru

GraphQLは、サーバーとクライアントの両方が、各タイプで使用可能なフィールドを事前に知っていることを前提としています。場合によっては、クライアントはそれらのフィールドを(イントロスペクションを介して)検出できますが、サーバーの場合は常に事前に把握しておく必要があります。したがって、返されたデータに基づいてこれらのフィールドを動的に生成することは、実際には不可能です。

あなたcouldはカスタム JSONスカラー (graphql-type-jsonモジュール)を利用し、それをクエリに返します。

type Query {
  persons(area: String): JSON
}

JSONを利用することにより、返されたデータが特定の構造に適合するという要件を回避できるため、適切にフォーマットされたJSONであれば、何でも送信できます。

もちろん、これには重大な欠点があります。たとえば、以前に使用したタイプによって提供されたセーフティネットが失われます(文字通り任意の構造が返される可能性があり、間違ったものを返す場合は、クライアントが試行するまでそれを知ることができません。それを使用すると失敗します)。また、返されたデータ内のフィールドに対してリゾルバーを使用する機能も失います。

しかし...あなたの葬式:)

余談ですが、データをクライアントに送信する前に、データをフラット化して(質問で提案したように)配列にすることを検討します。クライアントコードを記述していて、動的にサイズが設定された顧客のリストを操作している場合、IDでキーを指定したオブジェクトよりも、配列を操作する方がはるかに簡単です。たとえば、Reactを使用していて、顧客ごとにコンポーネントを表示している場合は、そのオブジェクトを配列に変換して、とにかくマッピングします。 APIの設計では、クライアントの使いやすさを、データの追加処理を回避することよりも重視します。

17
Daniel Rearden

独自のGraphQLScalarTypeを記述して、オブジェクトと動的キー、許可するものと許可しないもの、または変換できないものを正確に記述することができます。

https://graphql.org/graphql-js/type/#graphqlscalartype を参照してください

taion/graphql-type-json を見ると、あらゆる種類のコンテンツを許可および変換するスカラーが作成されます。

https://github.com/taion/graphql-type-json/blob/master/src/index.js

1
Lukas

スキーマの動的キーで同様の問題があり、次のような解決策になりました:

query lookupPersons {
  persons {
    personKeys
    person3: personValue(key: "person1") {
      id
      name
    }
  }
}

戻り値:

{
  data: {
    persons: {
      personKeys: ["person1", "person2", "person3"]
      person3: {
        id: "person3"
        name: "Mike"
      }
    }
  }
}

複雑さをクエリにシフトすることで、応答の形状が簡素化されます。 JSONアプローチと比較した場合の利点は、クライアントからの逆シリアル化が不要なことです。

0
teebszet