DEV Community

Rhodlib
Rhodlib

Posted on • Updated on • Originally published at blog.rhodlib.me

My first blog with MERN Stack (Back-end)

All about my blog: Back-end

Back-end blog: How?

In this article, I am going to explain how I created the backend for my blog,
what technogies I used and why, this is not a step-by-step guide, it is only a resource if you don't know how to start making your own blog, maybe this can help you on the technologies you need to learn. We have a lot of information on the internet and sometimes it is a little difficult to find a correct answer to our problems.

All the code of my backend is here



Index

  • Dependencies
    • ExpressJS
    • Mongoose
    • dotenv
    • cors
    • validator
    • bcryptjs
    • jsonwebtoken
    • slugify
  • Database
    • MongoDB
  • Structure
    • Controllers
    • db
    • middlewares
    • models
    • routes


Dependencies

In a few words, I will try to explain these dependencies and why I use them.


ExpressJS

The language we use to make this blog is JavaScript, for that reason i use NodeJS for the backend, NodeJS allows us to run JavaScript on the server side.

ExpressJS is nothing more than a web framework for NodeJS, it is robust and has a lot of features to make our lives easier when using NodeJS, for example it allows us to configure a server in 6 lines of code or less.

const express = require("express"); // 1
const app = express(); // 2

app.listen(3000, function () {
  // 3
  console.log("Server listening on port 3000"); // 4
}); //5
Enter fullscreen mode Exit fullscreen mode
  1. Why ExpressJS? Because is the most popular framework for NodeJS, And when it comes to getting a job, it is the most demanded.

  2. Are there other frameworks for NodeJS? Sure! we have other awesomes frameworks for NodeJS.

  3. How can install express on my server folder? if you has the package.json file on your folder, only need to run the following command
    $ npm install --save express

  4. It's hard to use? No, you really have all the information you need in the official Docs


Mongoose and MongoDB

As the official website says, mongoose is a elegant mongodb object modeling for NodeJS, what does that mean?.

Well, MongoDB is a system of databases NoSQL(Not Only SQL),
is a document-based database, we can store information in
JSON (JavaScript Object Notation) format within documents and these documents are saved in collections with an ID provided by MongoDB.

But the only way we have to keep organized the data entering and leaving the database is mongoose. Has functions to create a Schema and models.

What is a Schema? Schema is an Object that allows us to declare certain values ​​and generate validations before sending the data to the database. thus allowing us to manage the same structure in all the data that we store.

this is the schema of an article of my blog , this is how the article is store to the database

const { Schema, model } = require("mongoose");

const postSchema = new Schema(
  {
    image: String,
    title: {
      type: String,
      required: true,
    },
    description: String,
    markdown: {
      type: String,
      required: true,
    },
    createdAt: {
      type: Date,
      default: Date.now,
    },
    slug: {
      type: String,
      required: true,
      unique: true,
    },
  },
  {
    timestamps: true,
  }
);

const Post = model("Post", postSchema);

module.exports = Post;
Enter fullscreen mode Exit fullscreen mode

with this schema we create the model that we are going to use to store, save, delete and read the articles in the database.

Mongoose also allows us to connect to the database in a very easy way.

const mongoose = require("mongoose");

const URI = "mongodb://localhost/dbtest";

mongoose.connect(URI);

const connection = mongoose.connection;

connection.once("open", () => console.log("DB is connected"));
Enter fullscreen mode Exit fullscreen mode

Where can get more info about mongoose? mongoose has simple and easy-to-read docs


dotenv

dotenv is an npm package that allows us to create environment variables. An environment variable is a dynamic variable, it's as simple as writing a variable to an .env file and using it as a reference.
why do this? because we can protect sensitive information or data in the variable (database urls, passwords, tokens) when we upload the files to repositories or servers.

How can install dotenv in my project? $ npm install --save dotenv

How to configure dotenv to work with de project? only need to add a line of code in the top of the index.js.

require("dotenv").config();
Enter fullscreen mode Exit fullscreen mode

and then, you can create a .env file in the root of your project. more info about dotnev here


Cors

Cors is simple, I use it because allows me to have two servers at the same time on a different port and to be able to communicate between them, the backend server with nodemon and the frontend server with npm start

How can install cors? $ npm install --save cors

How usage cors? in the index.js of server or wherever you have your app

const express = require("express");
const cors = require("cors");
const app = express();

app.use(cors());
Enter fullscreen mode Exit fullscreen mode

more info about cors here


Validator

validator is a library of string validators and sanitizers

I use this on the User model, to validate the email property inside the userSchema

const validator = require("validator");

email: {
      type: String,
      required: true,
      unique: true,
      trim: true,
      lowercase: true,
      validate(value) {
        if (!validator.isEmail(value)) {
          throw new Error("Email is invalid");
        }
      },
    },
Enter fullscreen mode Exit fullscreen mode

you can see the full code here

How can install validator? $ npm install --save validator

Where can learn more about validator? you read more here


bcryptjs

bcryptjs is an npm package to encrypt, I use this for encrypt passwords, is very easy to use and secure with more than 700k+ downloads per week.

How install bcryptjs? $ npm install --save bcryptjs

How i use bcryptjs?

I use bcrypt in two functions of the "User model", one is creating a method for the user model through the userSchema to encript password.

User.js - Here is all the code

const bcrypt = require("bcryptjs");

//Here i created a method for userSchema called encryptPassword
userSchema.methods.encryptPassword = async (password) => {
  // get the password
  return await bcrypt.hash(password, 8); // 8 is a cicle this been hashed 8 times
  // and then return the password hashed by a function of bcrypt
};
Enter fullscreen mode Exit fullscreen mode

And later we need a function to desencrypt the password to validate password and for this I create a static method. static method is a function accesible in the model and not in the userObject

//Here i created a static method to find credentials and validate password
userSchema.statics.findByCredentials = async (email, password) => {
  //Get email and password
  const user = await User.findOne({ email }); //Search by email using the model (findOne is a static method)
  if (user) {
    // If user exist
    const isMatch = await bcrypt.compare(password, user.password);
    // use a function called compare from bcrypt and compare the password with the user.password in the database.
  }
};
Enter fullscreen mode Exit fullscreen mode

Slugify

Slugify is an npm package to create a slug from a string.

What the f*ck is an slug? slug is than simple like this "hello-how-are-you", it's a string with dash instead of spaces.

Why i need slug? In this blog I use slug like a unique property of each article, using his title as slug, why? because I can search and article for slug and not necesary by ID.

This is te best solution? Not, because the best practice is use an ID, but is right for me.

How slug help you? It's simple, finding by id, the route in the front-end it's something like this blog.rhodlib.me/article/5468fds1684541sdf18546516s8 this is not estetic, isn't nice to see.
but if find by slug, the route is something like this blog.rhodlib.me/article/all-about-my-blog-backend-how

How can install slugify? $ npm install --save slugify

How use slugify? Is very easy, let's see.

Post.js here is all the code.

const slugify = require("slugify");

//the function pre of the postSchema allows us run a function between the validate and the store article on the database
postSchema.pre("validate", function (next) {
  const post = this;

  if (post.title) {
    post.slug = slugify(post.title, { lower: true, strict: true }); // We use slugify to create the slug with the title, before save the article in the database
  }

  next();
});
Enter fullscreen mode Exit fullscreen mode

Where can get more info about slugify? you can go here


jsonwebtoken

jsonwebtoken is library to create validation tokens, I use this to validate user when they are connected in the app.

How use JWT in the blog? I use jwt in the following way.

User.js - here is de full code

const jwt = require("jsonwebtoken");

// here i created a method for each User called generateAuthToken
userSchema.methods.generateAuthToken = async function () {
  const user = this;

  const token = jwt.sign(
    // With jwt.sing() we create a token
    { _id: user._id.toString() }, // I pass the user id in an object
    process.env.AUTHTOKENSTRING // I use an environment variable to encrypt the token with a secret word
  );
  user.tokens = user.tokens.concat({ token }); // And then I put the new token in the user's token array
};
Enter fullscreen mode Exit fullscreen mode


Structure

I will explain the structure that I use in the project.

In the server folder I create a src folder in the first level, inside of this folder I create five folder more called:

  • controllers
  • db
  • middlewares
  • models
  • routes

and two files app.js and index.js


Controllers

here I create the controllers of the routes, when a request enters the server, the path executes a function, that function is stored in the controllers.

auth.controller.js - here is the full code

const authCtrl = {};

authCtrl.registerUser = async (req, res) => {
  // Code
};

authCtrl.loginUser = async (req, res) => {
  // Code
};

module.exports = authCtrl;
Enter fullscreen mode Exit fullscreen mode

DB

here I create a file called mongoose.js and store my access to database with mongoose.


Middlewares

here I create my middlewares, only have one. auth.js where realize the authorization for the login.


Models

here I create my two models, with their own schemas.


Routes

here I create the routes for the request. I have three files, within each one the routes are detailed:

  • auth.routes.js
  • post.routes.js
  • user.routes.js

auth.routes.js - here is the full code

const { loginUser } = require("../controllers/auth.controller");

router.post("/api/user/login", loginUser);

module.exports = router;
Enter fullscreen mode Exit fullscreen mode


THE END

And this is all the backend of my blog, I hope you find it interesting and guide you in case you do not know how to start

Top comments (1)

Collapse
 
kanchansaini profile image
Kanchan

Great post! I completely agree with you that React is a powerful tool for building dynamic and interactive user interfaces. In fact, I recently used React in a MERN stack course is used to create project a real-time chat application.
Thanks for sharing your insights on React in the MERN stack, and keep up the great work!