avatarMarcos Henrique da Silva

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

9573

Abstract

pan class="hljs-string">"@types/node"</span>: <span class="hljs-string">"^13.5.2"</span>, <span class="hljs-string">"@types/supertest"</span>: <span class="hljs-string">"^2.0.8"</span>, <span class="hljs-string">"chai"</span>: <span class="hljs-string">"^4.2.0"</span>, <span class="hljs-string">"mocha"</span>: <span class="hljs-string">"^7.0.1"</span>, <span class="hljs-string">"nodemon"</span>: <span class="hljs-string">"^2.0.2"</span>, <span class="hljs-string">"source-map-support"</span>: <span class="hljs-string">"^0.5.16"</span>, <span class="hljs-string">"supertest"</span>: <span class="hljs-string">"^4.0.2"</span>, <span class="hljs-string">"ts-node"</span>: <span class="hljs-string">"^8.6.2"</span>, <span class="hljs-string">"tslint"</span>: <span class="hljs-string">"^6.0.0"</span>, <span class="hljs-string">"typescript"</span>: <span class="hljs-string">"^3.7.5"</span> } }</pre></div><p id="53f4">We will create a file to control our mongoose integration. At the <b>app/common/services</b> folder let’s create a file called <b>mongoose.service.ts </b>and add the following:</p><div id="cc68"><pre><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">'mongoose'</span>;</pre></div><div id="f800"><pre><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MongooseService</span> { <span class="hljs-keyword">private</span> <span class="hljs-type">static</span> instance: MongooseService;</pre></div><div id="5453"><pre><span class="hljs-string">options</span> <span class="hljs-string">=</span> { <span class="hljs-attr">autoIndex:</span> <span class="hljs-literal">false</span>, <span class="hljs-attr">poolSize:</span> <span class="hljs-number">10</span>, <span class="hljs-attr">bufferMaxEntries:</span> <span class="hljs-number">0</span>, <span class="hljs-attr">useNewUrlParser:</span> <span class="hljs-literal">true</span>, <span class="hljs-attr">useUnifiedTopology:</span> <span class="hljs-literal">true</span> }<span class="hljs-string">;</span> <span class="hljs-string">count</span> <span class="hljs-string">=</span> <span class="hljs-number">0</span><span class="hljs-string">;</span></pre></div><div id="ddb4"><pre><span class="hljs-function"><span class="hljs-keyword">constructor</span><span class="hljs-params">()</span> <span class="hljs-comment">{ this.connectWithRetry(); }</span></span></pre></div><div id="d4b7"><pre><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title">getInstance</span>()</span> { <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.instance) { <span class="hljs-keyword">this</span>.instance = <span class="hljs-keyword">new</span> MongooseService(); } <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.instance; }</pre></div><div id="7a34"><pre><span class="hljs-title function_">getMongoose</span>(<span class="hljs-params"></span>){ <span class="hljs-keyword">return</span> mongoose; }</pre></div><div id="8ded"><pre><span class="hljs-title function_">connectWithRetry</span>(<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'MongoDB connection with retry'</span>); mongoose.<span class="hljs-title function_">connect</span>(<span class="hljs-string">"mongodb://mongo:27017/api-db"</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span>).<span class="hljs-title function_">then</span>(<span class="hljs-function">() =></span> { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'MongoDB is connected'</span>) }).<span class="hljs-keyword">catch</span>(<span class="hljs-function"><span class="hljs-params">err</span> =></span> { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'MongoDB connection unsuccessful, retry after 5 seconds. '</span>, ++<span class="hljs-variable language_">this</span>.<span class="hljs-property">count</span>); <span class="hljs-built_in">setTimeout</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">connectWithRetry</span>, <span class="hljs-number">5000</span>) }) };</pre></div><div id="03ac"><pre>}</pre></div><p id="c140">We are going to use this mongoose service to get the Mongoose to be used in our application, and also in a case of need any changes there we will only need to change one file instead of multiple ones.</p><p id="ba12">Now, at our <b>app/users/daos</b> folder, let’s create a file called <b>users.dao.ts </b>with the following:</p><div id="1640"><pre><span class="hljs-keyword">import</span> {MongooseService} <span class="hljs-keyword">from</span> <span class="hljs-string">'../../common/services/mongoose.service'</span>; <span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> shortUUID <span class="hljs-keyword">from</span> <span class="hljs-string">"short-uuid"</span>;</pre></div><div id="6bcb"><pre><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">UsersDao</span> { mongooseService: MongooseService = MongooseService.<span class="hljs-built_in">getInstance</span>(); <span class="hljs-keyword">private</span> <span class="hljs-type">static</span> instance: UsersDao;</pre></div><div id="2085"><pre><span class="hljs-attribute">Schema</span> <span class="hljs-operator">=</span> this.mongooseService.getMongoose().Schema<span class="hljs-comment">;</span></pre></div><div id="05c7"><pre>userSchema = <span class="hljs-keyword">new</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title class_">Schema</span>({ <span class="hljs-attr">_id</span>: <span class="hljs-title class_">String</span>, <span class="hljs-attr">name</span>: <span class="hljs-title class_">String</span>, <span class="hljs-attr">email</span>: <span class="hljs-title class_">String</span>, <span class="hljs-attr">description</span>: <span class="hljs-title class_">String</span>, <span class="hljs-attr">password</span>: <span class="hljs-title class_">String</span>, <span class="hljs-attr">permissionLevel</span>: <span class="hljs-title class_">Number</span> });</pre></div><div id="1e9d"><pre>User = <span class="hljs-keyword">this</span>.mongooseService.getMongoose().model(<span class="hljs-string">'Users'</span>, <span class="hljs-keyword">this</span>.userSchema);</pre></div><div id="0b2b"><pre><span class="hljs-function"><span class="hljs-keyword">constructor</span><span class="hljs-params">()</span> <span class="hljs-comment">{ }</span></span></pre></div><div id="018a"><pre><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title">getInstance</span>()</span> { <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.instance) { <span class="hljs-keyword">this</span>.instance = <span class="hljs-keyword">new</span> UsersDao(); } <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.instance; }</pre></div><div id="501f"><pre><span class="hljs-keyword">async</span> <span class="hljs-title function_">addUser</span>(<span class="hljs-params">userFields: <span class="hljs-built_in">any</span></span>) { userFields.<span class="hljs-property">_id</span> = shortUUID.<span class="hljs-title function_">generate</span>(); <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">new</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title class_">User</span>(userFields); <span class="hljs-keyword">await</span> user.<span class="hljs-title function_">save</span>(); <span class="hljs-keyword">return</span> userFields.<span class="hljs-property">_id</span>; }</pre></div><div id="04a7"><pre><span class="hljs-keyword">async</span> <span class="hljs-title function_">getUserByEmail</span>(<span class="hljs-params">email: <span class="hljs-built_in">string</span></span>) { <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">User</span>.<span class="hljs-title function_">findOne</span>({<span class="hljs-attr">email</span>: email}); }</pre></div><div id="9163"><pre><span class="hljs-keyword">async</span> <span class="hljs-title function_">removeUserById</span>(<span class="hljs-params">userId: <span class="hljs-built_in">string</span></span>) { <span class="hljs-keyword">await</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">User</span>.<span class="hljs-title function_">deleteOne</span>({<span class="hljs-attr">_id</span>: userId}); }</pre></div><div id="145b"><pre><span class="hljs-keyword">async</span> <span class="hljs-title function_">getUserById</span>(<span class="hljs-params">userId: <span class="hljs-built_in">string</span></span>) { <span

Options

class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">User</span>.<span class="hljs-title function_">findOne</span>({<span class="hljs-attr">_id</span>: userId}); }</pre></div><div id="73f7"><pre><span class="hljs-keyword">async</span> <span class="hljs-title function_">listUsers</span>(<span class="hljs-params">limit: <span class="hljs-built_in">number</span> = <span class="hljs-number">25</span>, page: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span></span>) { <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">User</span>.<span class="hljs-title function_">find</span>() .<span class="hljs-title function_">limit</span>(limit) .<span class="hljs-title function_">skip</span>(limit * page) .<span class="hljs-title function_">exec</span>(); }</pre></div><div id="ac83"><pre><span class="hljs-keyword">async</span> <span class="hljs-title function_">patchUser</span>(<span class="hljs-params">userFields: <span class="hljs-built_in">any</span></span>) { <span class="hljs-keyword">let</span> <span class="hljs-attr">user</span>: <span class="hljs-built_in">any</span> = <span class="hljs-keyword">await</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">User</span>.<span class="hljs-title function_">findById</span>(userFields.<span class="hljs-property">_id</span>); <span class="hljs-keyword">if</span>(user){ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">in</span> userFields) { user[i] = userFields[i]; } <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> user.<span class="hljs-title function_">save</span>(); } } }</pre></div><p id="0cc0">This file represents our integration with MongoDB using Mongoose for our <b>CRUD</b> users resources. We are using basic Mongoose integration to make the CRUD to work, but please remember, as always, to read the <a href="https://mongoosejs.com/">documentation</a> to understand it better and to use wisely at your own project. Also, you can find a good introduction of Mongoose <a href="https://readmedium.com/introduction-to-mongoose-for-mongodb-d2a7aa593c57">here</a>.</p><p id="1e8a">What we need to do now, is to change our users service to use our new file which will communicate with our MongoDB.</p><p id="32cd">Open now your <b>/app/users/services/user.services.ts </b>file and update it to call our new file and methods.</p><div id="18fe"><pre><span class="hljs-keyword">import</span> {<span class="hljs-variable constant_">CRUD</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">'../../common/interfaces/crud.interface'</span>; <span class="hljs-keyword">import</span> {<span class="hljs-title class_">GenericInMemoryDao</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">'../daos/in.memory.dao'</span>; <span class="hljs-keyword">import</span> {<span class="hljs-title class_">UsersDao</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">'../daos/users.dao'</span>; <span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">UsersService</span> <span class="hljs-keyword">implements</span> <span class="hljs-variable constant_">CRUD</span> { <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-attr">instance</span>: <span class="hljs-title class_">UsersService</span>; <span class="hljs-attr">dao</span>: <span class="hljs-title class_">GenericInMemoryDao</span>;</pre></div><div id="be94"><pre><span class="hljs-function"><span class="hljs-keyword">constructor</span><span class="hljs-params">()</span> <span class="hljs-comment">{ this.dao = GenericInMemoryDao.getInstance(); }</span></span></pre></div><div id="1358"><pre><span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-title">getInstance</span><span class="hljs-params">()</span>: UsersService {</span> <span class="hljs-keyword">if</span> (!UsersService.instance) { UsersService.instance = <span class="hljs-keyword">new</span> <span class="hljs-built_in">UsersService</span>(); } <span class="hljs-keyword">return</span> UsersService.instance; }</pre></div><div id="3609"><pre><span class="hljs-built_in">create</span>(resource: any) { return UsersDao<span class="hljs-selector-class">.getInstance</span>()<span class="hljs-selector-class">.addUser</span>(resource); }</pre></div><div id="b4a0"><pre><span class="hljs-built_in">deleteById</span>(resourceId: any) { return UsersDao<span class="hljs-selector-class">.getInstance</span>()<span class="hljs-selector-class">.removeUserById</span>(resourceId); };</pre></div><div id="ab8e"><pre><span class="hljs-title function_">list</span>(<span class="hljs-params">limit: <span class="hljs-built_in">number</span>, page: <span class="hljs-built_in">number</span></span>) { <span class="hljs-keyword">return</span> <span class="hljs-title class_">UsersDao</span>.<span class="hljs-title function_">getInstance</span>().<span class="hljs-title function_">listUsers</span>(limit, page); };</pre></div><div id="f569"><pre><span class="hljs-built_in">patchById</span>(resource: any) { return UsersDao<span class="hljs-selector-class">.getInstance</span>()<span class="hljs-selector-class">.patchUser</span>(resource); };</pre></div><div id="1661"><pre><span class="hljs-built_in">readById</span>(resourceId: any) { return UsersDao<span class="hljs-selector-class">.getInstance</span>()<span class="hljs-selector-class">.getUserById</span>(resourceId); };</pre></div><div id="1e26"><pre><span class="hljs-built_in">updateById</span>(resource: any) { return UsersDao<span class="hljs-selector-class">.getInstance</span>()<span class="hljs-selector-class">.patchUser</span>(resource); };</pre></div><div id="4fbf"><pre><span class="hljs-keyword">async</span> <span class="hljs-title function_">getByEmail</span>(<span class="hljs-params">email: <span class="hljs-built_in">string</span></span>) { <span class="hljs-keyword">return</span> <span class="hljs-title class_">UsersDao</span>.<span class="hljs-title function_">getInstance</span>().<span class="hljs-title function_">getUserByEmail</span>(email); } }</pre></div><p id="6d94">Note that we are importing a UsersDao now and using it at our functions.</p><div id="67c1"><pre><span class="hljs-keyword">import</span> {UsersDao} <span class="hljs-keyword">from</span> <span class="hljs-string">'../daos/users.dao'</span>; ...</pre></div><div id="9f0a"><pre>return UsersDao.getInstance<span class="hljs-params">()</span><span class="hljs-string">.getUserByEmail</span><span class="hljs-params">(email)</span>; <span class="hljs-string">...</span></pre></div><p id="59ca">And that’s it, every other piece of the code that will call the user service should not be changed.</p><blockquote id="6736"><p>Having a service that calls your DAO integration will make it easier for a future change of database and even a code maintenance</p></blockquote><p id="6daf">Now, let’s just run <code>npm run dev</code> and see our code working. You can stop and re-run it and you will see that our data is intact ;) That’s it, MongoDB up and running for us.</p><p id="78f1">In this article we configured a MongoDB using the benefits of the Docker Containers and our architecture of code to make it as a smooth switch from a in-memory dao to the MongoDB.</p><p id="7384">Thanks for reading and see you at the <a href="https://readmedium.com/another-expressjs-api-tutorial-for-2020-part-10-configuring-permissions-3d93d7446456">next article</a>!</p><div id="5b2e" class="link-block"> <a href="https://readmedium.com/another-expressjs-api-tutorial-for-2020-part-10-configuring-permissions-3d93d7446456"> <div> <div> <h2>Another ExpressJS API tutorial for 2020, part 10 — Configuring Permissions</h2> <div><h3>Hi there, today we are going to configure one of the missing part of our API made with ExpressJS and Typescript, the…</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*eWYm3Dm7s0t8lLWYRW4pow.jpeg)"></div> </div> </div> </a> </div><p id="2066">tips:</p><ul><li>the full code of this article is <a href="https://github.com/makinhs/expressjs-api-tutorial/tree/010-configurando-mongodb">here</a></li><li>don’t forget to use a nice app to test your API such as <a href="https://www.postman.com/">Postman</a> or <a href="https://insomnia.rest/">Insomnia</a></li><li>I know you still didn’t… Read the ExpressJS <a href="https://expressjs.com/en/4x/api.html">documentation</a>!</li><li>Learn Docker, start at their <a href="https://docs.docker.com/get-docker/">Documentation</a>!</li><li>Learn Mongoose, start also at their <a href="https://mongoosejs.com/docs/guide.html">Documentation</a>!</li><li>Complete project is <a href="https://github.com/makinhs/expressjs-api-tutorial">here</a>! (Includes even the non existing articles yet)</li></ul></article></body>

Another ExpressJS API tutorial for 2021, part 10— MongoDB!

Hey there, in this article we are going to use the advantage of our previously Docker configuration to add a MongoDB to our API made with ExpressJS and Typescript!

Hi there, if it is your first time arriving here we are creating a series on how to build an API using ExpressJS and Typescript. The first article can be found here.

Just as a quick overview, here is the series of articles that we are writing:

Welcome back again, so in this article we are going to remove our handmade in memory database to add a real database that in this case it will be a MongoDB.

How should we start?

First, make sure to be using the latest version of our project that can be found here.

Now, let’s update our docker-composer.yml file:

version: '3'
services:
  api:
    command: npm run test-dev
    build: .
    volumes:
      - ./api:/app
    links:
      - mongo
    networks:
      - backend
    ports:
      - "3000:3000"
mongo:
    image: mongo
    volumes:
      - ./data:/data/db
    networks:
      - backend
    ports:
      - "27017:27017"
networks:
  backend:
    driver: bridge

Thanks to the Docker, with a few lines of code we have our MongoDB ready to use. Couldn’t be that easy right? Since we are using a Docker containers, the MongoDB will be used via container and you wouldn’t need to do any extra steps to have it ready to use at your application. Now, let’s go configure it at our ExpressJS API!

First of all, make sure that you have installed all the required dependencies, so please update your package.json and run npm install

{
  "name": "expressjs-api-tutorial",
  "version": "0.0.1",
  "description": "Tutorial of how to create a REST API using ExpressJS",
  "main": "dist/app.js",
  "scripts": {
    "tsc": "tsc",
    "dev-debug": "nodemon --watch . --ext ts --exec \"npm run tsc\"",
    "start": "npm run tsc && node ./dist/app.js",
    "test-dev": "nodemon --watch . --ext ts --exec \"mocha -r ts-node/register test/**/*.test.ts\"",
    "dev": "nodemon --watch . --ext ts --exec \"docker-compose build && docker-compose up\"",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/makinhs/expressjs-api-tutorial.git"
  },
  "keywords": [
    "REST",
    "API",
    "ExpressJS",
    "NodeJS"
  ],
  "author": "Marcos Silva",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/makinhs/expressjs-api-tutorial/issues"
  },
  "homepage": "https://github.com/makinhs/expressjs-api-tutorial#readme",
  "dependencies": {
    "argon2-pass": "^1.0.2",
    "express": "^4.17.1",
    "jsonwebtoken": "^8.5.1",
    "mongoose": "^5.8.11",
    "short-uuid": "^3.1.1"
  },
  "devDependencies": {
    "@types/chai": "^4.2.8",
    "@types/express": "^4.17.2",
    "@types/mocha": "^7.0.1",
    "@types/mongoose": "^5.7.0",
    "@types/node": "^13.5.2",
    "@types/supertest": "^2.0.8",
    "chai": "^4.2.0",
    "mocha": "^7.0.1",
    "nodemon": "^2.0.2",
    "source-map-support": "^0.5.16",
    "supertest": "^4.0.2",
    "ts-node": "^8.6.2",
    "tslint": "^6.0.0",
    "typescript": "^3.7.5"
  }
}

We will create a file to control our mongoose integration. At the app/common/services folder let’s create a file called mongoose.service.ts and add the following:

import mongoose from 'mongoose';
export class MongooseService {
    private static instance: MongooseService;
options = {
        autoIndex: false,
        poolSize: 10,
        bufferMaxEntries: 0,
        useNewUrlParser: true,
        useUnifiedTopology: true
    };
    count = 0;
constructor() {
        this.connectWithRetry();
    }
public static getInstance() {
        if (!this.instance) {
            this.instance = new MongooseService();
        }
        return this.instance;
    }
getMongoose(){
        return mongoose;
    }
connectWithRetry() {
        console.log('MongoDB connection with retry');
        mongoose.connect("mongodb://mongo:27017/api-db", this.options).then(() => {
            console.log('MongoDB is connected')
        }).catch(err => {
            console.log('MongoDB connection unsuccessful, retry after 5 seconds. ', ++this.count);
            setTimeout(this.connectWithRetry, 5000)
        })
    };
}

We are going to use this mongoose service to get the Mongoose to be used in our application, and also in a case of need any changes there we will only need to change one file instead of multiple ones.

Now, at our app/users/daos folder, let’s create a file called users.dao.ts with the following:

import {MongooseService} from '../../common/services/mongoose.service';
import * as shortUUID from "short-uuid";
export class UsersDao {
    mongooseService: MongooseService = MongooseService.getInstance();
    private static instance: UsersDao;
Schema = this.mongooseService.getMongoose().Schema;
userSchema = new this.Schema({
        _id: String,
        name: String,
        email: String,
        description: String,
        password: String,
        permissionLevel: Number
    });
User = this.mongooseService.getMongoose().model('Users', this.userSchema);
constructor() {
    }
public static getInstance() {
        if (!this.instance) {
            this.instance = new UsersDao();
        }
        return this.instance;
    }
async addUser(userFields: any) {
        userFields._id = shortUUID.generate();
        const user = new this.User(userFields);
        await user.save();
        return userFields._id;
    }
async getUserByEmail(email: string) {
        return this.User.findOne({email: email});
    }
async removeUserById(userId: string) {
        await this.User.deleteOne({_id: userId});
    }
async getUserById(userId: string) {
        return this.User.findOne({_id: userId});
    }
async listUsers(limit: number = 25, page: number = 0) {
        return this.User.find()
            .limit(limit)
            .skip(limit * page)
            .exec();
    }
async patchUser(userFields: any) {
        let user: any = await this.User.findById(userFields._id);
        if(user){
            for (let i in userFields) {
                user[i] = userFields[i];
            }
            return await user.save();
        }
    }
}

This file represents our integration with MongoDB using Mongoose for our CRUD users resources. We are using basic Mongoose integration to make the CRUD to work, but please remember, as always, to read the documentation to understand it better and to use wisely at your own project. Also, you can find a good introduction of Mongoose here.

What we need to do now, is to change our users service to use our new file which will communicate with our MongoDB.

Open now your /app/users/services/user.services.ts file and update it to call our new file and methods.

import {CRUD} from '../../common/interfaces/crud.interface';
import {GenericInMemoryDao} from '../daos/in.memory.dao';
import {UsersDao} from '../daos/users.dao';
export class UsersService implements CRUD {
    private static instance: UsersService;
    dao: GenericInMemoryDao;
constructor() {
        this.dao = GenericInMemoryDao.getInstance();
    }
static getInstance(): UsersService {
        if (!UsersService.instance) {
            UsersService.instance = new UsersService();
        }
        return UsersService.instance;
    }
create(resource: any) {
        return UsersDao.getInstance().addUser(resource);
    }
deleteById(resourceId: any) {
        return UsersDao.getInstance().removeUserById(resourceId);
    };
list(limit: number, page: number) {
        return UsersDao.getInstance().listUsers(limit, page);
    };
patchById(resource: any) {
        return UsersDao.getInstance().patchUser(resource);
    };
readById(resourceId: any) {
        return UsersDao.getInstance().getUserById(resourceId);
    };
updateById(resource: any) {
        return UsersDao.getInstance().patchUser(resource);
    };
async getByEmail(email: string) {
        return UsersDao.getInstance().getUserByEmail(email);
    }
}

Note that we are importing a UsersDao now and using it at our functions.

import {UsersDao} from '../daos/users.dao';
...
return UsersDao.getInstance().getUserByEmail(email);
...

And that’s it, every other piece of the code that will call the user service should not be changed.

Having a service that calls your DAO integration will make it easier for a future change of database and even a code maintenance

Now, let’s just run npm run dev and see our code working. You can stop and re-run it and you will see that our data is intact ;) That’s it, MongoDB up and running for us.

In this article we configured a MongoDB using the benefits of the Docker Containers and our architecture of code to make it as a smooth switch from a in-memory dao to the MongoDB.

Thanks for reading and see you at the next article!

tips:

  • the full code of this article is here
  • don’t forget to use a nice app to test your API such as Postman or Insomnia
  • I know you still didn’t… Read the ExpressJS documentation!
  • Learn Docker, start at their Documentation!
  • Learn Mongoose, start also at their Documentation!
  • Complete project is here! (Includes even the non existing articles yet)
Expressjs
API
Mongodb
Typescript
Tutorial
Recommended from ReadMedium