0
votes

I've the following structure in my schema:

type gn_Feature implements Some_Interface {
  s_description: String
  s_id: URL!
  some_parent: gn_Feature
}

As you can see, each gn_Feature has an another linked gn_Feature object (the linking is handled elsewhere, it doesn't really matter). By my current understanding, you only need to define the resolvers for the return types, so my resolvers look like the following:

export const resolvers = Object.assign(
  {},
  {
    DateTime: DateTime,
    Date: DateTime,
    Time: RegularExpression("Time", /^\d{2}:\d{2}(:\d{2})?$/),
    URL,
    Query: {
       gn_Feature: gn_FeatureResolver
    },
    gn_Feature: gn_FeatureResolver
  }
);

But, my queries fail with the following error if I don't explicitly define the resolver for the nested field, like so:

gn_Feature: {some_parent: gn_FeatureResolver}

Error:

"message": "Resolve function for \"gn_Feature.s_description\" returned undefined"

My resolver function doesn't even get invoked for my nested object when I don't specify it like the above. My backend consists of some voodoo transpiling of GraphQL queries into SparQL queries which return data back so I won't post the resolver code as I utilize one universal resolver for many fields. I'd like to avoid having to specify resolvers for each nested field as that's going be extremely tedious (I have dozens of types with dozens of fields). Any clarifications are welcome, as I'm completely baffled.

Example GraphQL query:

gn_Feature(some_field:"AD", last:2){
  s_description,
  s_id
  some_parent{
    s_description 
  }
}
1

1 Answers

1
votes

When executing a query, only the value of any particular field is initially unknown and needs to be resolved... everything else, like the types, selection sets, etc. is already known. A resolver is a function called to resolve a specific field. In GraphQL.js, there are no resolvers for types.

Apollo muddies the waters a bit in this regard, since for convenience, the API for makeExecutableSchema allows you to define custom scalars by including them in the resolver map. Additionally, even though interfaces and unions don't have resolvers either, Apollo lets you use the resolver map to specify a __resolveType function for these abstract types as well. Apollo's docs actually define a resolver as "a function that connects schema fields and types to various backends." However, in the context of GraphQL in general, you should think of a resolvers as "a functions that resolves the value of a field".

So, given a type called gn_Feature and a field called some_parent, this is the correct way to structure your resolvers:

const resolvers = {
  gn_Feature: {
    some_parent: someResolverFunction
  }
}

Also note that Query and Mutation are both types themselves, so if you have a query called gn_Feature, you are actually resolving a field called gn_Feature for the Query type.