Search code examples
mongodbtypescriptmongoosetypegraphqltypegoose

Combining Type-GraphQL with Typegoose using Multiple Decorators


I'm using Type-GraphQl (which is a Typescript library that lets you automatically generate GraphQL schemas and resolvers with Typescript classes) and Typegoose (which does the same thing for Mongoose queries). I'm trying to cut down on the number of files defining my data, ideally so I've only got one source of truth for the data in both GQL and MongoDB.

Can these two libraries be combined so that I'm using a single Typescript class to describe both my GQL schema and my Mongoose types in one file?

For example, a simple type-graphql file (defining a "book" type) looks like this:

import { Field, ObjectType } from "type-graphql";
import { InStock } from "./gql/shared/types";

@ObjectType()
export class Book extends InStock {
  @Field()
  title: string;

  @Field()
  publicationDate: Date;

  @Field()
  author: string;

  @Field()
  pages: number;
}

The typegoose class looks quite similar but uses @prop decorators to set properties for the schema:

import * as mongoose from "mongoose";
import { getModelForClass, prop } from "@typegoose/typegoose";
import { InStock } from "./mongoose/shared/types";

class BookClass extends InStock {
  @prop()
  public title: string;
  @prop()
  public author: string;
  @prop()
  public publicationDate: Date;
  @prop()
  public pages: number;
  @prop()
}

export const Book = getModelForClass(BookClass);

Is it possible to combine these two types with both decorators in the same file, or will that break typegoose/type-graphl? Like this:

import * as mongoose from "mongoose";
import { Field, ObjectType } from "type-graphql";
import { InStock } from "./shared";
import { getModelForClass, prop } from "@typegoose/typegoose";

export class Book extends InStock { // Export type-graphql here...
  @prop()
  @Field()
  public title: string;
  @prop()
  @Field()
  public author: string;
  @prop()
  @Field({ nullable: true })
  public publicationDate?: Date;
  @prop()
  @Field()
  public pages: number;
}

export const Book = getModelForClass(BookClass); /// Export typegoose here...

Solution

  • i have seen many users using typegoose & typegraphql successfully together

    @ObjectType()
    export class Book extends InStock {
      @prop()
      @Field()
      public title: string;
    
      @prop()
      @Field()
      public author: string;
    
      @prop()
      @Field({ nullable: true })
      public publicationDate?: Date;
    
      @prop()
      @Field()
      public pages: number;
    }
    
    export const Book = getModelForClass(BookClass);
    

    Here some offical examples from TypeGraphQL