Express.js Tutorial for Beginners
What is Express.js?
Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It's the most popular Node.js framework and makes building web applications and APIs much easier than using Node's built-in HTTP module alone.
Why Use Express.js?
Express.js simplifies web development with Node.js by providing:
- Simplified Routing: Easy-to-use routing system for handling HTTP requests
- Middleware Support: Modular components that can handle requests and responses
- Template Engines: Support for dynamic HTML generation
- Database Integration: Easy integration with various databases
- Large Ecosystem: Extensive middleware and plugins available
Setting Up Express.js
Step 1: Create a Project Directory
mkdir my-express-app
cd my-express-app
Step 2: Initialize npm Project
npm init -y
Step 3: Install Express.js
npm install express
Step 4: Install Nodemon for Development
npm install --save-dev nodemon
Step 5: Update package.json Scripts
{
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
}
}
Creating Your First Express App
Create a file called app.js and add the following code:
// Import Express
const express = require('express');
// Create an Express application
const app = express();
const port = 3000;
// Define a route
app.get('/', (req, res) => {
res.send('Hello, Express!');
});
// Start the server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Run your application with:
npm run devVisit
http://localhost:3000in your browser to see your first Express app!Understanding Routing
Routing refers to how an application's endpoints (URIs) respond to client requests. Express provides a simple and powerful routing system.
Basic Routes
// GET route for homepage app.get('/', (req, res) => { res.send('Welcome to the homepage!'); }); // GET route for about page app.get('/about', (req, res) => { res.send('About us page'); }); // POST route for creating data app.post('/users', (req, res) => { res.send('Creating a new user'); }); // PUT route for updating data app.put('/users/:id', (req, res) => { res.send(`Updating user ${req.params.id}`); }); // DELETE route for deleting data app.delete('/users/:id', (req, res) => { res.send(`Deleting user ${req.params.id}`); });Route Parameters
Route parameters are named URL segments used to capture values. They can be accessed using
req.params:// Route with parameter app.get('/users/:userId', (req, res) => { const userId = req.params.userId; res.send(`User ID: ${userId}`); }); // Multiple parameters app.get('/users/:userId/posts/:postId', (req, res) => { const { userId, postId } = req.params; res.send(`User ${userId}, Post ${postId}`); });Query Parameters
Query parameters are key-value pairs in the URL after the question mark. They can be accessed using
req.query:// URL: /search?q=nodejs&sort=popular app.get('/search', (req, res) => { const { q, sort } = req.query; res.send(`Searching for: ${q}, sorted by: ${sort}`); });Middleware
Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application's request-response cycle.
Application-Level Middleware
// Custom middleware const logger = (req, res, next) => { console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`); next(); }; // Apply middleware to all routes app.use(logger); // Built-in middleware app.use(express.json()); // Parse JSON bodies app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodiesRoute-Specific Middleware
// Middleware for specific route app.use('/admin', (req, res, next) => { console.log('Admin middleware'); next(); }); app.get('/admin/dashboard', (req, res) => { res.send('Admin Dashboard'); });Error Handling Middleware
// Error handling middleware (must be last) app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!'); });Template Engines
Express supports various template engines for generating dynamic HTML. Let's use EJS as an example:
Install EJS
npm install ejsSet Up View Engine
app.set('view engine', 'ejs');Create Views Directory
mkdir viewsCreate a Template
Create
views/index.ejs:<!DOCTYPE html> <html> <head> <title><%= title %></title> </head> <body> <h1><%= heading %></h1> <p><%= message %></p> </body> </html>Render Template
app.get('/', (req, res) => { res.render('index', { title: 'My Express App', heading: 'Welcome to Express.js', message: 'This is a dynamic page!' }); });Building a REST API
Express is excellent for building REST APIs. Let's create a simple user management API:
Mock Data
// Mock user data let users = [ { id: 1, name: 'John Doe', email: 'john@example.com' }, { id: 2, name: 'Jane Smith', email: 'jane@example.com' } ];API Routes
// GET all users app.get('/api/users', (req, res) => { res.json(users); }); // GET user by ID app.get('/api/users/:id', (req, res) => { const user = users.find(u => u.id === parseInt(req.params.id)); if (!user) { return res.status(404).json({ error: 'User not found' }); } res.json(user); }); // POST new user app.post('/api/users', (req, res) => { const newUser = { id: users.length + 1, name: req.body.name, email: req.body.email }; users.push(newUser); res.status(201).json(newUser); }); // PUT update user app.put('/api/users/:id', (req, res) => { const user = users.find(u => u.id === parseInt(req.params.id)); if (!user) { return res.status(404).json({ error: 'User not found' }); } user.name = req.body.name || user.name; user.email = req.body.email || user.email; res.json(user); }); // DELETE user app.delete('/api/users/:id', (req, res) => { const index = users.findIndex(u => u.id === parseInt(req.params.id)); if (index === -1) { return res.status(404).json({ error: 'User not found' }); } users.splice(index, 1); res.json({ message: 'User deleted successfully' }); });Static Files
Express can serve static files like CSS, JavaScript, and images:
// Serve static files from 'public' directory app.use(express.static('public')); // Now you can access files like: // http://localhost:3000/css/style.css // http://localhost:3000/js/script.js // http://localhost:3000/images/logo.pngCommon Middleware Packages
Here are some useful Express middleware packages:
CORS
npm install cors const cors = require('cors'); app.use(cors()); // Enable CORS for all routesMorgan (HTTP Request Logger)
npm install morgan const morgan = require('morgan'); app.use(morgan('combined')); // Log HTTP requestsHelmet (Security)
npm install helmet const helmet = require('helmet'); app.use(helmet()); // Set security headersError Handling Best Practices
// 404 handler (must be after all other routes) app.use((req, res, next) => { res.status(404).json({ error: 'Not Found' }); }); // Global error handler (must be last) app.use((err, req, res, next) => { console.error(err.stack); // Don't leak error details in production const message = process.env.NODE_ENV === 'production' ? 'Something went wrong!' : err.message; res.status(err.status || 500).json({ error: message, ...(process.env.NODE_ENV === 'development' && { stack: err.stack }) }); });Next Steps
Now that you understand Express.js basics, you can explore:
- Database integration with MongoDB
- User authentication and authorization
- Testing Express applications
- Deploying Express apps to production
Conclusion
Express.js provides a solid foundation for building web applications and APIs with Node.js. Its minimal approach and extensive middleware ecosystem make it a popular choice among developers. Master these fundamentals and you'll be well on your way to building robust web applications.