DEV Community

Nilesh Kumar
Nilesh Kumar

Posted on

Learning Node.js with Express.js: A Day-by-Day Guide

Learning Node.js with Express.js: A Day-by-Day Guide

This document outlines a detailed day-by-day learning path to understand and practice Node.js with Express.js. By the end of the guide, you'll have created a project with login and signup functionality, including password hashing and token management.


Day 1: Introduction to Node.js

Topics:

  • What is Node.js and why use it?
  • Installing Node.js and npm
  • Understanding the Node.js runtime
  • Exploring Node.js modules and npm packages

Exercises:

  1. Install Node.js and verify the installation with node -v and npm -v.
  2. Create a "Hello World" application using Node.js.

Code:

// hello.js
console.log('Hello, World!');

// Run using: node hello.js
Enter fullscreen mode Exit fullscreen mode
  1. Explore the fs and path modules with small examples.

Code:

const fs = require('fs');
const path = require('path');

// Create a file
fs.writeFileSync('example.txt', 'This is an example');

// Read the file
const data = fs.readFileSync('example.txt', 'utf-8');
console.log(data);

// Get file path info
console.log(path.basename('example.txt'));
Enter fullscreen mode Exit fullscreen mode

Day 2: Setting Up Express.js

Topics:

  • Introduction to Express.js
  • Setting up a basic Express application
  • Understanding middleware and routes

Exercises:

  1. Install Express.js using npm.

Command:

npm install express
Enter fullscreen mode Exit fullscreen mode
  1. Create a basic Express.js server with a "Hello World" route.

Code:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello World!');
});

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode
  1. Explore middleware by adding custom logging and error-handling middleware.

Code:

// Custom logging middleware
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

// Error-handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});
Enter fullscreen mode Exit fullscreen mode

Day 3: Routing and API Basics

Topics:

  • Understanding routes in Express.js
  • HTTP methods: GET, POST, PUT, DELETE
  • Using query parameters and route parameters

Exercises:

  1. Create routes for basic CRUD operations.

Code:

app.get('/items', (req, res) => res.json({ message: 'Get all items' }));
app.post('/items', (req, res) => res.json({ message: 'Create an item' }));
app.put('/items/:id', (req, res) => res.json({ message: `Update item ${req.params.id}` }));
app.delete('/items/:id', (req, res) => res.json({ message: `Delete item ${req.params.id}` }));
Enter fullscreen mode Exit fullscreen mode
  1. Build an API endpoint to return JSON data.

Code:

app.get('/api/data', (req, res) => {
  res.json({ id: 1, name: 'Example Item' });
});
Enter fullscreen mode Exit fullscreen mode
  1. Use Postman or a similar tool to test your routes.

Day 4: Working with Middleware

Topics:

  • Built-in middleware in Express.js
  • Third-party middleware (e.g., body-parser, cors)
  • Writing custom middleware

Exercises:

  1. Use body-parser to parse incoming request bodies.

Code:

const bodyParser = require('body-parser');
app.use(bodyParser.json());
Enter fullscreen mode Exit fullscreen mode
  1. Add cors to your application for handling cross-origin requests.

Code:

const cors = require('cors');
app.use(cors());
Enter fullscreen mode Exit fullscreen mode
  1. Write a custom middleware function for logging request details.

Code:

app.use((req, res, next) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
  next();
});
Enter fullscreen mode Exit fullscreen mode

Day 5: Connecting to a Database (MongoDB)

Topics:

  • Introduction to MongoDB and Mongoose
  • Connecting your Node.js application to MongoDB
  • Defining and using schemas and models

Exercises:

  1. Set up a local MongoDB instance or use MongoDB Atlas.
  2. Install Mongoose and connect it to your MongoDB database.

Code:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/mydatabase', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

mongoose.connection.once('open', () => {
  console.log('Connected to MongoDB');
});
Enter fullscreen mode Exit fullscreen mode
  1. Create a schema and model for user data.

Code:

const userSchema = new mongoose.Schema({
  email: String,
  password: String,
});

const User = mongoose.model('User', userSchema);
module.exports = User;
Enter fullscreen mode Exit fullscreen mode

Day 6: Password Hashing with bcrypt

Topics:

  • Why hash passwords?
  • Using the bcrypt library to hash and compare passwords

Exercises:

  1. Install the bcrypt library.

Command:

npm install bcrypt
Enter fullscreen mode Exit fullscreen mode
  1. Create a function to hash a password before saving it to the database.

Code:

const bcrypt = require('bcrypt');

const hashPassword = async (password) => {
  const salt = await bcrypt.genSalt(10);
  return await bcrypt.hash(password, salt);
};

// Usage
const hashedPassword = await hashPassword('mypassword');
Enter fullscreen mode Exit fullscreen mode
  1. Write a function to compare hashed passwords during login.

Code:

const isMatch = await bcrypt.compare('mypassword', hashedPassword);
console.log(isMatch); // true or false
Enter fullscreen mode Exit fullscreen mode

Day 7: Token Management with JWT

Topics:

  • Introduction to JSON Web Tokens (JWT)
  • Creating and verifying JWTs
  • Storing and using tokens for authentication

Exercises:

  1. Install the jsonwebtoken library.

Command:

npm install jsonwebtoken
Enter fullscreen mode Exit fullscreen mode
  1. Create a function to generate a token after a successful login.

Code:

const jwt = require('jsonwebtoken');

const generateToken = (userId) => {
  return jwt.sign({ id: userId }, process.env.JWT_SECRET, { expiresIn: '1h' });
};

const token = generateToken('12345');
console.log(token);
Enter fullscreen mode Exit fullscreen mode
  1. Add middleware to verify tokens for protected routes.

Code:

app.use((req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ message: 'Unauthorized' });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (err) {
    res.status(401).json({ message: 'Invalid token' });
  }
});
Enter fullscreen mode Exit fullscreen mode

Day 8: Creating the Login and Signup Features

Topics:

  • Building the signup route
  • Building the login route
  • Validating user input

Exercises:

  1. Create a /signup route to register users and save hashed passwords.

Code:

app.post('/signup', async (req, res) => {
  const { email, password } = req.body;
  const hashedPassword = await hashPassword(password);

  const user = new User({ email, password: hashedPassword });
  await user.save();
  res.status(201).json({ message: 'User registered successfully' });
});
Enter fullscreen mode Exit fullscreen mode
  1. Create a /login route to authenticate users and return a token.

Code:

app.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const user = await User.findOne({ email });

  if (!user || !(await bcrypt.compare(password, user.password))) {
    return res.status(401).json({ message: 'Invalid credentials' });
  }

  const token = generateToken(user._id);
  res.json({ token });
});
Enter fullscreen mode Exit fullscreen mode
  1. Add input validation using a library like express-validator.

Code:

const { body, validationResult } = require('express-validator');

app.post(
  '/signup',
  [body('email').isEmail(), body('password').isLength({ min: 6 })],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { email, password } = req.body;
    const hashedPassword = await hashPassword(password);
    const user = new User({ email, password: hashedPassword });
    await user.save();
    res.status(201).json({ message: 'User registered successfully' });
  }
);
Enter fullscreen mode Exit fullscreen mode

The added code examples provide practical steps for each learning topic, ensuring hands-on practice throughout the journey.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay