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:
- Install Node.js and verify the installation with
node -v
andnpm -v
. - Create a "Hello World" application using Node.js.
Code:
// hello.js
console.log('Hello, World!');
// Run using: node hello.js
- Explore the
fs
andpath
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'));
Day 2: Setting Up Express.js
Topics:
- Introduction to Express.js
- Setting up a basic Express application
- Understanding middleware and routes
Exercises:
- Install Express.js using npm.
Command:
npm install express
- 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}`);
});
- 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!');
});
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:
- 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}` }));
- Build an API endpoint to return JSON data.
Code:
app.get('/api/data', (req, res) => {
res.json({ id: 1, name: 'Example Item' });
});
- 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:
- Use
body-parser
to parse incoming request bodies.
Code:
const bodyParser = require('body-parser');
app.use(bodyParser.json());
- Add
cors
to your application for handling cross-origin requests.
Code:
const cors = require('cors');
app.use(cors());
- 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();
});
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:
- Set up a local MongoDB instance or use MongoDB Atlas.
- 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');
});
- 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;
Day 6: Password Hashing with bcrypt
Topics:
- Why hash passwords?
- Using the
bcrypt
library to hash and compare passwords
Exercises:
- Install the
bcrypt
library.
Command:
npm install bcrypt
- 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');
- Write a function to compare hashed passwords during login.
Code:
const isMatch = await bcrypt.compare('mypassword', hashedPassword);
console.log(isMatch); // true or false
Day 7: Token Management with JWT
Topics:
- Introduction to JSON Web Tokens (JWT)
- Creating and verifying JWTs
- Storing and using tokens for authentication
Exercises:
- Install the
jsonwebtoken
library.
Command:
npm install jsonwebtoken
- 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);
- 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' });
}
});
Day 8: Creating the Login and Signup Features
Topics:
- Building the signup route
- Building the login route
- Validating user input
Exercises:
- 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' });
});
- 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 });
});
- 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' });
}
);
The added code examples provide practical steps for each learning topic, ensuring hands-on practice throughout the journey.
Top comments (0)