web-dev-qa-db-ja.com

単一のオブジェクトを返すものと同じエンドポイントを使用して、GraphQLでオブジェクトの配列を返す方法は?

私はGraphQL APIを作成しています。ここでは、パラメーターが指定されていない場合に、IDで自動車オブジェクトを取得したり、すべての自動車を取得したりできます。

以下のコードを使用すると、パラメーターとしてidを指定することで、単一の自動車オブジェクトを正常に取得できます。

ただし、オブジェクトの配列を期待する場合、つまりパラメーターをまったく指定しない場合、GraphiQLで結果が得られません。

schema.js

let cars = [
  { name: "Honda", id: "1" },
  { name: "Toyota", id: "2" },
  { name: "BMW", id: "3" }
];

const CarType = new GraphQLObjectType({
  name: "Car",
  fields: () => ({
    id: { type: GraphQLString },
    name: { type: GraphQLString }
  })
});

const RootQuery = new GraphQLObjectType({
  name: "RootQueryType",
  fields: {
    cars: {
      type: CarType,
      args: {
        id: { type: GraphQLString }
      },
      resolve(parent, args) {
        if (args.id) {
          console.log(cars.find(car => car.id == args.id));
          return cars.find(car => car.id == args.id);
        }
        console.log(cars);
        //***Problem Here***
        return cars;
      }
    }
  }
});

テストクエリとそれぞれの結果:

クエリ1

{
  cars(id:"1"){
    name
  }
}

クエリ1の応答(成功)

{
  "data": {
    "cars": {
      "name": "Honda"
    }
  }
}

クエリ2

{
  cars{
    name
  }
}

クエリ2応答(失敗)

{
  "data": {
    "cars": {
      "name": null
    }
  }
}

どんな助けでも大歓迎です。

3
Haris Ghauri

車と車のリストは、事実上2つの異なるタイプです。フィールドは一度に単一のCarオブジェクトに解決できず、Carオブジェクトの配列を別の解決できません。

nameフィールドは単一のオブジェクトに解決されるが、代わりに配列に解決されると伝えたため、クエリはcarsに対してnullを返します。その結果、配列オブジェクトでnameというプロパティが検索され、存在しないため、nullが返されます。

これはいくつかの方法で処理できます。物事を1つのクエリに保持するには、filterの代わりにfindを使用して、クエリのタイプをリストに変更できます。

cars: {
  type: new GraphQLList(CarType), // note the change here
  args: {
    id: {
      type: GraphQLString
    },
  },
  resolve: (parent, args) => {
    if (args.id) {
      return cars.filter(car => car.id === args.id);
    }
    return cars;
  }
}

または、これを2つの個別のクエリに分割することもできます。

cars: {
  type: new GraphQLList(CarType),
  resolve: (parent, args) => cars,
},
car: {
  type: CarType,
  args: {
    id: {
      // example of using GraphQLNonNull to make the id required
      type: new GraphQLNonNull(GraphQLString)
    },
  },
  resolve: (parent, args) => cars.find(car => car.id === args.id),
}

その他の例とオプションについては、 docs を確認してください。

5
Daniel Rearden