How to Build a Simple Server with Node.js and Express.js

How to Build a Simple Server with Node.js and Express.js

Introduction

Are you ready to journey back to the basics of backend development with Express.js? Whether you're a newcomer eager to explore the world of server-side programming or an experienced developer seeking a refresher, this article is for you.

In this comprehensive guide, we'll delve into the essentials of building a simple server using Node.js and Express.js. From setting up the environment to handling routes and connecting to a database, we'll demystify the process step by step.

Express.js is not just another framework – it's a powerful tool that empowers developers to create scalable and efficient web applications. By mastering its fundamentals, you'll gain the skills needed to tackle a wide range of backend challenges.

So, dust off your coding skills and join me on this adventure as we unlock the secrets of Express.js together. Whether you're a beginner or a seasoned developer, there's something here for everyone.

Ready to get started? Let's dive in!

Setting up the Environment

First things first, let's set up our project environment. We'll need Node.js installed on our machine. Once that's done, let's create a new directory for our project and initialize it with npm.

mkdir blog-tuts
cd blog-tuts
npm init -y

Next, we'll install the necessary dependencies: Express.js, Mongoose for MongoDB connectivity, and dotenv for managing environment variables.

npm install express mongoose dotenv

With our dependencies installed, let's create a .env file to store our environment variables.

PORT=3001
dbURI=your_mongodb_connection_string

Creating the Server

Now, let's create our index.js file, which will serve as the entry point for our application.

require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const app = express()
const port = process.env.PORT
const blogRouter = require('./routes/blogRoutes')

//middleware 
app.use(express.json({limit: '50mb'}))
app.use(express.urlencoded({extended: 'true', limit: '50mb'}))

//routes 
app.use('/blogs', blogRouter)

//connect to mongoose 
mongoose.connect(process.env.dbURI)
.then(() => {
    //server 
    app.listen(port, () => {
        console.log(`Listening on http://localhost:${port}`)
    })
})

Defining our Routes

In our routes/BlogRoutes.js file, we define the routes for our blog application.

const {getBlogs, getBlog, postBlog, updateBlog, deleteBlog} = require('../controllers/blogController')
const express = require('express')

const router = express.Router()

//all
router.get('/', getBlogs)

//index
router.get('/:_id', getBlog)

//post 
router.post('/', postBlog)

//update
router.patch('/:_id', updateBlog)

//delete 
router.delete('/:_id', deleteBlog)

module.exports = router;

Working with MongoDB

We'll define our Blog model in models/blogModel.js to interact with our MongoDB database.

const mongoose = require('mongoose'); 

const blogSchema = new mongoose.Schema({
    title: {
        type: String
    }, 
    body: {
        type: String
    }, 
    author: {
        type: String
    }
}, {timestamps: true})

module.exports = mongoose.model('Blog', blogSchema)

Controller Logic

In our controllers/blogController.js file, we define the logic for handling CRUD operations on our Blog model.

const Blog = require('../models/blogModel')
const mongoose = require('mongoose')

//retrieve all blogs
const getBlogs = async (req, res) => {
    try{
        const blogs = await Blog.find().sort({createdAt: -1})
        res.status(200).json(blogs)
    }catch(error) {
        res.status(500).json({error: error.message})
    }
}

//retrieve a single blog
const getBlog = async (req, res) => {
    const {_id} = req.params;
    if(!mongoose.Types.ObjectId.isValid(_id)){
        return res.status(400).json({error: 'Not a valid ID!'})
    }
    try{
        const blog = await Blog.findById(_id)
        if(blog) {
            return res.status(200).json(blog)
        }
        return res.status(404).json({error: 'Blog not Found!'})

    }catch(error) {
        res.status(500).json({error: error.message})
    }
}

//post a blog
const postBlog = async (req, res) => {
    const {title, body, author} = req.body; 
    try {
        const blog = await Blog.create({title, body, author})
        if(blog) {
            return res.status(200).json({message: 'Blog SuccessfUlly Created'})
        }
        return res.status(400).json({message: 'Blog not Created!'})
    }catch(error) {
        res.status(500).json({error: error.message})
    }
}

//update a blog
const updateBlog = async (req, res) => {
 const {_id} = req.params; 
  if (!mongoose.Types.ObjectId.isValid(_id)) {
    return res.status(400).json({error: 'Not a valid ID!'});
  }
 try{
    const updatedBlog = await Blog.findByIdAndUpdate({_id}, {...req.body})
    if(updatedBlog){
        return res.status(200).json(updatedBlog)
    }
    return res.status(400).json({error: 'BLog not Found!'})
 }catch(error) {
    res.status(500).json({error: error.message})
 }
}

//delete a blog
const deleteBlog = async (req, res) => {
    const {_id} = req.params; 
     if (!mongoose.Types.ObjectId.isValid(_id)) {
       return res.status(400).json({error: 'Not a valid ID!'});
     }
    try {
        const deletedBlog = await Blog.findOneAndDelete({_id})
        if(deletedBlog) {
            return res.status(200).json({message: 'Blog successfully Deleted!'})
        }
        return res.status(404).json({error: 'Blog not Found!'})

    }catch(error) {
        res.status(500).json({error: error.message})
    }
}

module.exports = {getBlogs, getBlog, updateBlog, postBlog, deleteBlog}

Conclusion

And there you have it! We've successfully built a simple server using Node.js and Express.js, complete with routes for handling CRUD operations on our blog application. This is just the beginning of your journey into backend development. Feel free to explore further, add more features, and enhance your skills. Happy coding!