27 March 2023 (updated: 19 December 2024)
Chapters
After you choose the MongoDB database in your system, you’ll probably also use an ODM library. The most popular is Mongoose or a library built on top of it - Typegoose. In this article, we’ll cover their main differences when working specifically with the NestJS framework.
You probably already know that Typegoose is essentially a way to use Mongoose with TypeScript and that would be your criteria when choosing the library. But it’s a bit more to this when working with the NestJS framework because there is a Mongoose wrapper created by NestJS authors - @nestjs/mongoose and when You look at the syntax - it seems almost identical to Typegoose.
Let’s break down the differences between them so it’s easier to decide what approach you should choose in your project - using @nestjs/mongoose package or Typegoose. When integrating MongoDB with a NestJS application, you’ll find examples and code snippets demonstrating how to set up a NestJS application to work with MongoDB using TypeScript and packages like Typegoose.
@nestjs/mongoose is a library dedicated to the Nest framework so it comes with full support of its DI workflow. On the other hand, Typegoose can be used in any other NodeJS project so you will have to either integrate it with Nest on your own or use community packages.
Although both packages allow defining schemas using similar decorators, their interfaces vary and Typegoose provides more options than the Nest wrapper. For example - `@Schema()` decorator takes only Mongoose’s defined schema options, whereas `@modelOptions()` in addition to this offers access to an existing connection and some custom Typegoose configuration options.
With `@nestjs/mongoose`, if you want to manually modify the schema definition based on the metadata, you can use the `DefinitionsFactory` class. This approach can be useful when it’s difficult to represent everything using decorators.
Both packages allow defining instances and static methods. Here are examples on how we can define class methods in both packages:
As you can see, we have to create additional interfaces when using mongoose, Typegoose however allows us to get type information from classes. The definitions are also more natural as they are contained within a class like regular methods. With the Nest package, you have to use the `statics` and `methods` properties outside of the class, which slightly reduces readability and becomes a less natural approach when it comes to using classes.
Both packages support hooks. In @nestjs/mongoose you can use them in the factory method of module imports. Typegoose offers support with @pre() and @post() decorators.
You can add custom queries in both packages, but you will probably encounter type issues in Mongoose. The difference between a query method and a static function on the model is that the function would not be chainable
Virtual properties can be created in Typegoose using ES6 get & set functions, whereas with the Nest package you have to use the `virtual` property outside of the class, which similarly to class methods, feels less natural to work with.
Although Mongoose already can infer types from schema definition and its Nest wrapper has cool features you’ll still benefit more when using Typegoose. It also has better documentation and community support. The question is - do you have the time and resources to integrate Typegoose into your Nest project? If so, I’d personally give it a chance.