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)