# Mongoose Model Conventions

# Introduction

Mongoose (opens new window) is the most popular MongoDB object modeling tool. It provides a straight-forward, schema-based solution to model your application data. It includes built-in type casting, validation, query building, business logic hooks and more, out of the box.

⚠️ Mongoose is not managed by the ExpressWebJs core team. Please, report any issues found with the library in the appropriate repository.

To get started:

1.Install the mongoose package.

npm install mongoose --save
Copied!
  1. Install mongoose unique validator
npm install mongoose-unique-validator
Copied!

let’s create a Users model. Models typically live in the app directory.

# Establishing Mongoose connection

Interaction with the mongoose is possible once you setup a connection. To do that update your database details in .env file located in the root directory. Let assume we are working with MySql database.

DB_CONNECTION = mongoose; //database
DB_HOST = localhost; //database host
DB_PORT = 27017; //database port
DB_USER = database_user;
DB_PASSWORD = database_password;
DB_DATABASE = database;
Copied!

You can also check database configuration file in 📘Config/database.ts. as it is reading the values in the .env file

/*
  |--------------------------------------------------------------------------
  | MongoDB Database
  |--------------------------------------------------------------------------
  |
  | Here we define connection settings for MongoDB database.
  |
  | npm i --save mongoose
  |
  */
  mongoose: {
    client: "mongoose",
    host: env("DB_HOST"),
    port: env("DB_PORT"),
    user: env("DB_USER"),
    password: env("DB_PASSWORD"),
    database: env("DB_DATABASE"),
    useCreateIndex: env("DB_USECREATEINDEX"),
    useNewUrlParser: env("DB_USENEWURLPARSER"),
    useUnifiedTopology: env("DB_USEUNIFIEDTOPOLOGY"),
    connection: {
      connection_link: `mongodb://${env("DB_USER")}:${env("DB_PASSWORD")}@${env("DB_HOST")}:${env("DB_PORT")}/${env("DB_DATABASE")}`,
    },
  },
Copied!

Once that is done, we can now create our model.

The easiest way to create a nosql model instance is using the make-nosql-model command:

 ts-node maker make-nosql-model User
Copied!

Now, let’s look at an example User model, which we will use to retrieve and store information from our users database table:

import { mongoose, Schema, Document } from "Elucidate/Database/NoSQLModel";
import uniqueValidator from "mongoose-unique-validator";

export interface UserInterface extends Document {
  first_name: string;
  last_name: string;
  email: string;
  password: string;
}

const UserSchema: Schema = new Schema({
  first_name: { type: String, required: true },
  first_name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
});

UserSchema.set("timestamps", true);
UserSchema.plugin(uniqueValidator);

const User = mongoose.model<UserInterface>("User", UserSchema);

export default User;
Copied!

# Model and Repository

To get started, let’s create a Users model. Models typically live in the App directory.

The easiest way to create a model instance is using the make-sql-model command:

 ts-node maker make-nosql-model User
Copied!

If you would like to generate a database migration when you generate the model, you may use the –migration or –m option:

 ts-node maker make-nosql-model User -m
Copied!

OR

ts-node maker make-nosql-model User -migration
Copied!

Now, let’s look at an example User model, which we will use to retrieve and store information from our users database table:

import { mongoose, Schema, Document } from "Elucidate/Database/NoSQLModel";
import uniqueValidator from "mongoose-unique-validator";

export interface UserInterface extends Document {
  first_name: string;
  last_name: string;
  email: string;
  password: string;
}

const UserSchema: Schema = new Schema({
  first_name: { type: String, required: true },
  first_name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
});

UserSchema.set("timestamps", true);
UserSchema.plugin(uniqueValidator);

const User = mongoose.model<UserInterface>("User", UserSchema);

export default User;
Copied!

Lets create our UserRepository class in 📘App/Repository directory.

import User, { UserInterface } from "App/Model/User_model";
import { NOSQLRepository } from "Elucidate/Repository/NOSQLPD_repository";

export class UserRepository extends NOSQLRepository<UserInterface> {
  constructor() {
    super(User);
  }
}
Copied!

We can add other methods in our repository

import User from "App/Model/User_model";
import { NOSQLRepository } from "Elucidate/Repository/NOSQLPD_repository";

export class UserRepository extends NOSQLRepository<UserInterface> {
  constructor() {
    super(User);
  }

  async findByName(first_name: string, last_name: string) {
    return await this.findOne({ first_name, last_name });
  }
}
Copied!

Now we can use it in our UserService class in 📘App/Service/UserService directory.

import { UserRepository } from "App/Repository/UserRepository";

export class UserService {
  public async getUser(first_name: string, last_name: string): Promise<User> {
    return await new UserRepository().findByName(first_name, last_name);
  }
}
Copied!

We can also register UserRepository in AppServiceProvider and inject it in UserService

import { UserRepository } from "App/Repository/UserRepository";
import { UserService } from "App/Service/UserService";
import ServiceProvider from "Elucidate/Support/ServiceProvider";

export class AppServiceProvider extends ServiceProvider {
  /**
   * Register application services.
   * @return void
   */
  register(): Promise<void> {
    this.singleton(UserRepository);
    this.singleton(UserService);
  }
}
Copied!

We can now inject UserRepository into UserService

import { UserRepository } from "App/Repository/UserRepository";

export class UserService {
  constructor(private userRepository: UserRepository) {}

  public async getUser(first_name: string, last_name: string): Promise<User> {
    return await this.userRepository().findByName(first_name, last_name);
  }
}
Copied!