18-Nodejs Course 2023: Break: Code Refactor
Tags: node, typescript, mongodb, fastify
Published: 2022-10-31 14:37:29

---
title: 18-Nodejs Course 2023: Break: Code Refactor
published: true
description: 
series: Nodejs Course 2023
tags: nodejs, typescript, mongodb, fastify
#cover_image: 
# Use a ratio of 100:42 for best results.
---

Now our code started to be more complex, we need to enhance it more little bit.

Let's start with out database folder.

## Database Folder

We have so far two files, `connection.ts` which contains the connection class and `database` class which contains the database manager, but when we import them they are imported from their own files, let's wrap it in an index file.

```ts
// src/core/database/index.ts
import database from "./database";

export { Connection, default as connection } from "./connection";
export { Database } from "./database";
export default database;
```

So we export the connection object and its class, the database class and the database object.

But the only difference is that we exported the `database` as default, so we can import it like this:

```ts
import database from "core/database";

// do something with database
```

Now we can import them from the index file.

```ts
// src/index
import "app/routes";
import startApplication from "core/application";

// ❌ replace  this
import connection from "core/database/connection";
// ✅ with this
import { connection } from "core/database";

import "./config";

startApplication();

connection.connect();
```

## Moving the connection

Now let's move our database connection into the startApplication function.

```ts
// src/core/application.ts
import multipart from "@fastify/multipart";
import Fastify from "fastify";
import { connection } from "./database";
import router from "./router";

export default async function startApplication() {
  const server = Fastify();

  server.register(multipart, {
    attachFieldsToBody: true,
  });

  router.scan(server);

 // connect to database
  connection.connect();

  try {
    // 👇🏻 We can use the url of the server
    const address = await server.listen({ port: 3000 });

    console.log(`Start browsing using ${address}`);
  } catch (err) {
    server.log.error(err);
    process.exit(1); // stop the process, exit with error
  }
}
```

Let's remove the connection from the index.

```ts
// src/index.ts
import "app/routes";
import startApplication from "core/application";
import "./config";

startApplication();
```

We shall see the same, nothing changed.

## More Enhancements of startApplication

If we can see, there are two main functions that we can extract from the startApplication function, the first one is to connect to database and the other one is for requests handling, so let's split it into two functions.

```ts
import multipart from "@fastify/multipart";
import Fastify from "fastify";
import { connection } from "./database";
import router from "./router";

function connectToDatabase() {
  connection.connect();
}

async function connectToServer() {
  const server = Fastify();

  server.register(multipart, {
    attachFieldsToBody: true,
  });

  router.scan(server);

  try {
    // 👇🏻 We can use the url of the server
    const address = await server.listen({ port: 3000 });

    console.log(`Start browsing using ${address}`);
  } catch (err) {
    server.log.error(err);
    process.exit(1); // stop the process, exit with error
  }
}

export default async function startApplication() {
  connectToDatabase();
  connectToServer();
}
```

This is much easier to maintain and read, also if we want to add more options in the start application it won't be too complicated.

Want more enhancement? let's make a new directory called `requests` and move the `connectToServer` function into it.

```ts
// src/core/requests/index.ts
import multipart from "@fastify/multipart";
import Fastify from "fastify";
import router from "core/router";

export default async function startServer() {
  const server = Fastify();

  server.register(multipart, {
    attachFieldsToBody: true,
  });

  router.scan(server);

  try {
    // 👇🏻 We can use the url of the server
    const address = await server.listen({ port: 3000 });

    console.log(`Start browsing using ${address}`);
  } catch (err) {
    server.log.error(err);
    process.exit(1); // stop the process, exit with error
  }
}
```

And let's also move the connectToDatabase function into the database folder.

```ts
// src/core/database/index.ts
import connection from "./connection";
import database from "./database";

export function connectToDatabase() {
  connection.connect();
}

export { Connection } from "./connection";
export { Database } from "./database";
export default database;
```

Now let's update our startApplication function.

```ts
// src/core/application.ts
import { connectToDatabase } from "core/database";
import startServer from "core/requests";

export default async function startApplication() {
  connectToDatabase();
  startServer();
}
```

Pretty neat, right?

## Update connection class

Now let's update our connection class, we can split the database configuration in a method for example.

```ts
// src/core/database/connection.ts
import config from "@mongez/config";
import chalk from "chalk";
import { MongoClient } from "mongodb";
import database, { Database } from "./database";

export class Connection {
  /**
   * Mongo Client
   */
  public client?: MongoClient;

  /**
   * Database instance
   */
  public database?: Database;

  /**
   * Connect to the database
   */
  public async connect() {
    const { host, port, username, password, databaseName } =
      this.configurations;

    try {
      this.client = await MongoClient.connect(`mongodb://${host}:${port}`, {
        auth: {
          username: username,
          password: password,
        },
      });

      const mongoDBDatabase = await this.client.db(databaseName);

      this.database = database.setDatabase(mongoDBDatabase);

      console.log(
        chalk.green("Connected!"),
        !username || !password
          ? chalk.red("Your not making a secure authenticated connection!")
          : "",
      );
    } catch (error) {
      console.log(error);
    }
  }

  /**
   * Get database configurations
   */
  public get configurations() {
    return {
      host: config.get("database.host", "localhost"),
      port: config.get("database.port", 27017),
      username: config.get("database.username", ""),
      password: config.get("database.password", ""),
      databaseName: config.get("database.name", ""),
    };
  }
}

const connection = new Connection();

export default connection;
```

We just moved the configurations list into a method, this also will allow us to get the configurations from anywhere in the application later.

> Please note that the configurations is a getter method, so we can't call it like a function, we have to call it like a property.

## Conclusion

This practice should be in your regular development, it **MUST BE NOT** over-engineering, it's just a good practice to make your code more readable and maintainable from time to time.

## 🎨 Project Repository

You can find the latest updates of this project on [Github](https://github.com/hassanzohdy/nodejs-2023)

## 😍 Join our community

Join our community on [Discord](https://discord.gg/vtZE9YzaFz) to get help and support (Node Js 2023 Channel).

## 🎞️ Video Course (Arabic Voice)

If you want to learn this course in video format, you can find it on [Youtube](https://www.youtube.com/playlist?list=PLGO8ntvxgiZMJc7RN2lIq9WmMOlWZGzmz), the course is in Arabic language.

## 💰 Bonus Content 💰

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

- [Event Driven Architecture: A Practical Guide in Javascript](https://dev.to/hassanzohdy/event-driven-architecture-the-best-paradigm-that-i-love-to-work-with-in-javascript-and-node-js-1gnk)
- [Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript](https://dev.to/hassanzohdy/best-practices-for-case-styles-camel-pascal-snake-and-kebab-case-in-node-and-javascript-55oi)
- [After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
](https://dev.to/hassanzohdy/after-6-years-of-practicing-mongodb-here-are-my-thoughts-on-mongodb-vs-mysql-574b)

Packages & Libraries

- [Collections: Your ultimate Javascript Arrays Manager](https://dev.to/hassanzohdy/collections-your-ultimate-javascript-array-handler-3o15)
- [Supportive Is: an elegant utility to check types of values in JavaScript](https://dev.to/hassanzohdy/supportive-is-an-elegant-utility-to-check-types-of-values-in-javascript-1b3e)
- [Localization: An agnostic i18n package to manage localization in your project](https://dev.to/hassanzohdy/mongez-localization-the-simplest-way-to-translate-your-website-regardless-your-favorite-framework-4gi3)

 React Js Packages

- [useFetcher: easiest way to fetch data in React Js](https://dev.to/hassanzohdy/usefetcher-the-easiest-way-to-fetch-data-in-react-45o9)

Courses (Articles)

- [React Js: Let"s Create File Manager With React Js and Node Js](https://dev.to/hassanzohdy/lets-create-a-file-manager-from-scratch-with-react-and-typescript-chapter-i-a-good-way-to-expand-your-experience-5g4k)