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
Why ExpressJS? Because is the most popular framework for NodeJS, And when it comes to getting a job, it is the most demanded.
-
Are there other frameworks for NodeJS? Sure! we have other awesomes frameworks for NodeJS.
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
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;
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"));
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();
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());
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");
}
},
},
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
};
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.
}
};
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();
});
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
};
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;
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;
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)
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!