Exploring the NestJS framework using mongoose schema, interfaces, and DTOs: A deep dive

As a newcomer to nestJS and mongoDB, I find myself questioning the need to declare DTO, schema, and interface for every collection we aim to store in our mongoDB. For example, I have a collection (unfortunately named collection) and this is the DTO I've created:

export class CollectionDto {
  readonly description: string;
  readonly name: string;
  readonly expiration: Date;
}

Here is the interface:

import { Document } from 'mongoose';

export interface Collection extends Document {
  readonly description: string;
  readonly name: string;
  readonly expiration: Date;
}

And the schema:

import * as mongoose from 'mongoose';

export const CollectionSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  description: {
    type: String,
    required: false,
  },
  expiration: {
    type: String,
    required: true,
  }
});

My concern lies in the necessity of having three separate objects with very similar content. Initially, this seems quite peculiar to me.

Answer №1

My experience with mongoose in plain nodejs has been extensive, and I am now delving into NestJS as well. Mongoose provides Schema and Model to interact with mongodb for document operations such as creation, querying, updating, and deletion. In plain mongoose, defining a model typically looks like this:

import * as mongoose from 'mongoose';

export const CollectionSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  description: {
    type: String,
    required: false,
  },
  expiration: {
    type: String,
    required: true,
  }
});
const Collection = mongoose.model('collections', CollectionSchema);

The 'Collection' here serves as the mongoose model. All good so far.

When working with NestJs and following API best practices, using a DTO (Data Transfer Object) is recommended. NestJs prefers classes over interfaces in this context. When defining a Mongoose schema, you can also define Model/Schema as shown below:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type CollectionDocument = Collection & Document;

@Schema()
export class Collection {
  @Prop()
  name: string;

  @Prop()
  description: number;

  @Prop()
  expiration: string;
}

export const CollectionSchema = SchemaFactory.createForClass(Collection);

For services and controllers in NestJs, both model and DTO are utilized:

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Collection, CollectionDocument } from './schemas/collection.schema';
import { CollectionDto } from './dto/collection.dto';

@Injectable()
export class CollectionService {
  constructor(@InjectModel(Collection.name) private collectionModel: Model<CollectionDocument>) {}

  async create(createColDto: CollectionDto): Promise<Collection> {
    const createdCollection = new this.collectionModel(createColDto);
    return createdCollection.save();
  }

  async findAll(): Promise<Collection[]> {
    return this.collectionModel.find().exec();
  }
}

Utilize Swagger for automatic documentation of your APIs post implementation. NestJS Mongo Techniques

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered: Jest-dom is throwing a TypeError because $toString is not recognized as a function on a project using Typescript, React

I have been facing a challenge while setting up jest and @testing-library/jest-dom for my typescript/react/next.js website. Each time I try running the tests, an error occurs, and I am struggling to identify the root cause. This issue has been perplexing ...

The operator is being invoked multiple times beyond originally anticipated

I am currently working on developing code that paginates a result set using the expand operator until a specific number of resources have been fetched. Below is the code snippet I have written so far (excluding the actual async call logic): import { Obser ...

Issue: Module '@nrwl/workspace/src/utilities/perf-logging' not found

I attempted to run an Angular project using nxMonorepo and made sure to install all the necessary node modules. However, when I tried running the command "nx migrate --run-migrations" in my directory PS C:\Users\Dell\Desktop\MEANAPP&bso ...

Troubleshooting Clarifai object error while invoking "model.predict" within Angular Framework

I've been attempting to utilize Clarifai's color API to extract the different colors present in an image. Unfortunately, I am encountering challenges when trying to call the API, as it consistently returns empty objects. Below is the snippet of ...

The typed union type FormGroup in Angular stands out for its versatility and robustness

Within my application, users select a value from a dropdown menu to determine which type of FormGroup should be utilized. These formGroups serve as "additional information" based on the selection made. I am currently working with three distinct types of f ...

Unable to retrieve information from the database during the http.get request

Hey everyone, I've encountered an issue that I need help with. I'm working on retrieving data from a database using an HTTP call and then returning it to the front end. Here's what I have so far: app.get('/contentHandler/post/frontPage ...

"What is the most efficient way to break up an array into its maximum length and iterate over

Using Firebase to send push notifications, but encountering the following error: { Error: tokens list must not contain more than 500 items at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42: ...

Having trouble connecting to the MongoDB Replicaset pods from other pods, receiving the error message: "unable to access 10.1.231.87:27017 | connect

I have successfully set up a MongoDB statefulset in a microk8s Kubernetes cluster. To connect to the PRIMARY replica, I use the pod's IP address in my host's terminal with the following command: mongosh "mongodb://10.1.231.87:27017/test". In thi ...

The Angular variable binding issue persists upon reloading the page or browser, yet functions seamlessly when navigating between routes

My subscribe button displays the text "Subscribe" when the page loads, but upon reloading the page, the text disappears. The button text is controlled by TypeScript code, and strangely, when I navigate to another route, the text magically reappears. HTML ...

How to showcase the date in a unique format using Angular

Does anyone know of a JavaScript ES7 method that can convert the output of new Date() into the format shown below? If there isn't a built-in method, I am willing to manually parse or find/replace it myself. 2020-06-30 07.49.28 I would like the da ...

What are the best ways to improve the efficiency of my filtering function

Currently, I'm working on a project involving Angular, NestJS, GraphQL, and MongoDB. I have created a modal component for filtering data that contains multiple fields. However, I am not confident that the code I wrote follows best practices and am see ...

Trouble seeing span in ion-item in Ionic 2: How can I display plain text instead?

It seems like I may be overlooking something, as I am experiencing an issue with adding a span to an Ion Item, where the span is not being rendered, nor is the div. <ion-card> <ion-card-title> </ion-card-title> <div> < ...

Unlocking the Power of Dependent Types in TypeScript: Unveiling Type by Property Name Declaration

In an attempt to tie the types to the arguments passed, consider the following example: type NS = "num" | "str" type Data<T extends NS> = T extends "num" ? number : string type Func<T extends NS> = (x: Data<T> ...

Manipulate numerous documents within MongoDB by updating them with varying data in each

I have a list of unique IDs: idList = ["5ec42446347f396fc3d86a3d", "5ec422d4347f396fc3d86a3c", "5ecefaf0aead3070fbdab7dd"] I want to update the documents that match these IDs with different data in each one: const currentData = await Data.updateMany( ...

Encountering issues with Next.js routing - Pages failing to load as expected

Having some trouble with the routing in my Next.js application. I've created a page named about.tsx within the "pages" directory, but when trying to access it via its URL (localhost:3000/about), the page fails to load correctly and displays: This Pa ...

Apollo Client's useQuery function is causing unnecessary refetches when using Next.js' router.push method

Currently, I'm facing an issue where a query within a useQuery Apollo Client hook is being re-run unnecessarily every time Next.js's router.push function is triggered. The problem code snippet looks like this: const Parent = () => { useQuery ...

Configuring Angular routes based on service method invocation

I have my routes configured in @NgModule. I also have a service that determines which parts of the application to display based on specific conditions. I need to call this service and adjust the routes according to its output. Issue: The route configurati ...

Mongoose stores only the `_id` and `_v` fields in the database

This particular issue has been identified as a duplicate question, but unfortunately, it remains unanswered. The core problem lies in the fact that when attempting to save a new record using mongoose through a post request, only minimal information is act ...

What is the proper method to modify a nested array using Mongoose?

Here's what I have been working on. I have an AnswerSchema with a nested comments array that I am attempting to update. const AnswerSchema = new Schema({ user: { type: Schema.Types.ObjectId, ref: 'user', }, ...

How can I arrange selected options at the top in MUI autocomplete?

I am currently working with mui's useAutocomplete hook https://mui.com/material-ui/react-autocomplete/#useautocomplete Is there a way to programmatically sort options and place the selected option at the top using JavaScript sorting, without resorti ...