GraphQL Schema Design for Returning Lists of Things

How to define a graphQL type and build a schema that will return an instance or collection of the same type.

Dummy data

const people = [
  {
    "_id": "1",
    "firstName": "John",
    "lastName": "Masse"
  },
  {
    "_id": "2",
    "firstName": "Joe",
    "lastName": "Random"
  },
];

Building the Person type

const Person = new GraphQLObjectType( {
  name: 'Person',
  fields: {
    _id: { type: GraphQLID },
    firstName: { type: GraphQLString },
    lastName: { type: GraphQLString },
  }
} );

Now that we have our type, we will now define a schema that leverages returning either a single Person or a collection of Person.

const schema = new GraphQLSchema( {
  query: new GraphQLObjectType( {
    name: 'PersonQuery',
    fields: { // fields define the root of our query
      person: {
        type: Person,
        args: { // arguments we accept from the query
          _id: { type: GraphQLID }
        },
        resolve: function( _, args ) {
          return people.find( person => {
            return person._id === args._id
          } );
        }
      },
      people: {
        type: new GraphQLList( Person ),
        resolve: function( _, args ) {
          return people;
        }
      }
    }
  } ),
} );

The magic in this schema occurs within the type property. By passing our Person type to GraphQLList type GraphQL will use the type as defined in Person to qualify the collection at the time of your query.

// graphQL query for a single person
{
  person( _id: "1" ) {
    firstName
  }
}

// will return
{
  firstName: "John"
}

// graphQL query for the collection
{
  people {
    firstName
  }
}

// will yield
[
  {
    firstName: "John"
  },
  {
    firstName: "Joe"
  }
]