Search code examples
node.jsstructuregraphql-jsmodularityresolver

Rolling back resolve function from GraphQLObjectType to another


I'm currently studying GraphQL and as part of the developing process, i'm interested with modularization of my code - i do understand how to write query, but fail to understand how to correctly implement query of queries.

That is the rootQuery.js

const {
  GraphQLInt,
  GraphQLList,
  GraphQLObjectType,
  GraphQLSchema,
  GraphQLFloat,
  GraphQLString
} = require("graphql");

const bankRootQuery = require('../graphql/queries/bank.queries')

const rootQuery = new GraphQLObjectType({
  name: "rootQuery",
  fields: {
    bankRootQuery: { type: bankRootQuery, resolve: () => { console.log(bankRootQuery.resolve) } } 
  }
});
module.exports = new GraphQLSchema({
  query: rootQuery
});

And here is the bankRootQuery.js:

const { GraphQLObjectType, GraphQLInt, GraphQLNonNull, GraphQLID, GraphQLList } = require("graphql");

  const BankType = require('../types/bank.type');
  const models = require('../../models/models_handler');

module.exports = new GraphQLObjectType({
    name: "bankRootQuery",
    fields: {
        getbanks: {
            type: new GraphQLList(BankType),
            resolve: () => {
                return models.getBanks()
            }
        },
        getbankByID: {
            type: BankType,
            args: {
              bankID: { name: "bankID", type: GraphQLInt }
            },
            resolve: (_, args) =>  { 
                if (!models.getBanks().has(args.bankID))
                    throw new Error(`Bank with ID ${args.bankID} doesn't exists`);
                return models.getBank(args.bankID);}
        }
    }
});

Assining bankRootQuery to the scheme object instead of rootQuery works perfectly fine, but using the rootQuery yields with null result when querying using GraphiQL - The Documentation Explorer structure seems to be in proper manner, so i'm guessing the problem is with the resolve function, which i don't understand how to define correctly.

Here is the result when querying using GraphQL:

{
  "data": {
    "bankRootQuery": null
  }
}

Solution

  • If a field resolves to null, then execution for that "branch" of the graph ends. Even if the field's type is an object type, none of the resolvers for its "children" fields will be called. Imagine if you had a field like user -- if the field resolves to null, then it makes no sense to try to resolve the user's name or email.

    Your resolver for the bankRootQuery field just logs to the console. Because it doesn't have a return statement, its return value is undefined. A value of undefined is coerced into a null. Since the field resolved to null, execution halts.

    If you want to return something other than null, then your resolver needs to return something -- even if it's just an empty object ({}). Then the resolvers for any "child" fields will work as expected.

    In general, I would advise against nesting your queries like this -- just keep them at the root level. For additional details around how field resolution works, check out this post.