In our graphql server there are essentially two types that exist in parallel.
The custom types are the actual entities that exist within our application before them being exposed by graphql.
Is it possible to configure graphql-codegen to type the parent parameter of a resolver with an internal type while keeping the default resolver return type?
In some cases, I need to limit some of the fields exposed to graphql. For example, imagine I have an internal type with some interface like:
interface Pet {
petId: string;
name: string;
birthdate: string;
type: 'dog' | 'fish' | 'cat';
}
and a graphql schema like so:
enum PetType {
dog,
fish,
cat
}
type Pet {
petId: String!
name: String!
age: Int!
type: PetType!
}
Query {
findPet(petId: String!): Pet
}
Now, for whatever reason I've decided not to expose the Pet's birthdate but I need to access the Pet's birthdate to calculate the age.
const myRootPetResolver: Query['findPet'] = async (_, args, context) => {
const { petId } = args;
const { database } = context;
// fetch some data from the database
const pet = await database.findPet(petId);
return pet;
}
const myPetAgeResolver: PetResolver['age'] = async (parent, args, context) => {
const { birthdate } = parent; // ❌ Error birthdate does not exist on graphql type
const { database } = context;
return new Date().getFullYear() - new Date(birthdate).getFullYear();
}
The above won't work because the parent type is the graphql generated type and not the internal type from that I've returned in the root resolver.
I tried with a graphql-codegen plugin using a property called mappers
which allows to override the default parent and return type of resolvers with a custom type. While this sort of solves the problem, it overrides the return type completely with the custom type.. making the generated types from the graphql schema meaningless.
Is there a way to override only the parent type without return type? allowParentTypeOverride
looked promising but this seems to require manually indicating the parent type in each resolver.
Here Charly, from The Guild, working on GraphQL Code Generator.
Have you tried enabling the allowParentTypeOverride
option to be able to manually force the parent
type?
Here is an example of how you would setup your resolvers:
import { Resolvers, UserResolvers } from '../resolvers-types'
type Email = string
interface UserModel {
email: Email
}
const userResolvers: UserResolvers<any, UserModel> = {
email: (parent) => {
parent
// ^ of type `UserModel` (not the GraphQL one)
return ''
}
}
const resolvers: Resolvers = {
User: userResolvers
}