I'm using the typescript-mongodb
plugin to graphql-codegen
to generate Typescript types for pulling data from MongoDB and outputting it via GraphQL on Node.
My input GraphQL schema looks like this
type User @entity{
id: ID @id,
firstName: String @column @map(path: "first_name"),
...
The generated output Typescript types look correct
export type User = {
__typename?: 'User',
id?: Maybe<Scalars['ID']>,
firstName?: Maybe<Scalars['String']>,
...
And the corresponding DB object
export type UserDbObject = {
_id?: Maybe<String>,
first_name: Maybe<string>,
...
The problem is when actually sending back the mongo document as a UserDbObject
I do not get the fields mapped in the output. I could write a custom resolver that re-maps the fields back to the User
type, but that would mean I'm mapping the fields in two different places.
i.e. I do not get mapped fields from a resolver like this
userById: async(_root: any, args: QueryUserByIdArgs, _context: any) : Promise<UserDbObject> => {
const result = await connectDb().then((db) => {
return db.collection<UserDbObject>('users').findOne({'_id': args.id}).then((doc) => {
return doc;
});
})
...
return result as UserDbObject;
}
};
Is there a way to use the typescript-mongodb
plugin to only have to map these fields in the schema, then use the auto-generated code to resolve them?
You can use mappers
feature of codegen to map between your GraphQL types and your models types.
See:
Since all codegen plugins are independent and not linked together, you should do it manually, something like:
config:
mappers:
User: UserDbObject
This will make typescript-resolvers
plugin to use UserDbObject
at any time (as parent value, or as return value).
If you wish to automate this, you can either use the codegen programmatically (https://graphql-code-generator.com/docs/getting-started/programmatic-usage), or you can also create a .js
file instead of .yaml
file that will create the config section according to your needs.