How to return an array of objects in GraphQL, possibly using the same endpoint as the one that returns a single object?

29,119

A Car and a List of Cars are effectively two separate types. A field cannot resolve to a single Car object one time, and an array of Car object another.

Your query is returning null for the name because you told it the cars field would resolve to a single object, but it resolved to an array instead. As a result, it's looking for a property called name on the array object and since one doesn't exist, it's returning null.

You can handle this in a couple of different ways. To keep things to one query, you can use filter instead of find and change the type of your query to a List.

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

Alternatively, you could split this into two separate queries:

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),
}

Check the docs for more examples and options.

Share:
29,119
Haris Ghauri
Author by

Haris Ghauri

Updated on July 25, 2022

Comments

  • Haris Ghauri
    Haris Ghauri almost 2 years

    I am making a GraphQL API where I would be able to retrieve a car object by its id or retrieve all the cars when no parameter is provided.

    Using the code below, I am successfully able to retrieve a single car object by supplying id as a parameter.

    However, in the case where I would expect an array of objects i.e. when I supply no parameter at all, I get no result on 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;
          }
        }
      }
    });
    

    Test queries and their respective results:

    Query 1

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

    Query 1 Response (Success)

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

    Query 2

    {
      cars{
        name
      }
    }
    

    Query 2 Response (Fail)

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

    Any help would be much appreciated.