Introduction to Express.js
Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features for building single-page, multi-page, and hybrid web applications. It's known for its simplicity, speed, and unopinionated approach, allowing developers to structure their applications as they see fit.
Let's dive into the essential components of Express.js and explore how to use them effectively.
Setting Up an Express.js Server
To get started with Express.js, you'll need to have Node.js installed on your machine. Once that's done, you can create a new project and install Express:
mkdir my-express-app cd my-express-app npm init -y npm install express
Now, let's create a basic Express server:
const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello, Express!'); }); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); });
This simple server listens on port 3000 and responds with "Hello, Express!" when you visit the root URL.
Routing in Express.js
Routing refers to determining how an application responds to a client request to a particular endpoint. Express provides a simple and intuitive way to define routes:
app.get('/users', (req, res) => { res.send('Get all users'); }); app.post('/users', (req, res) => { res.send('Create a new user'); }); app.put('/users/:id', (req, res) => { res.send(`Update user with ID ${req.params.id}`); }); app.delete('/users/:id', (req, res) => { res.send(`Delete user with ID ${req.params.id}`); });
These routes demonstrate how to handle different HTTP methods and use route parameters.
Middleware in Express.js
Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application's request-response cycle, commonly denoted by a variable named next
.
Here's an example of a custom middleware:
const myMiddleware = (req, res, next) => { console.log(`${req.method} request to ${req.url}`); next(); }; app.use(myMiddleware);
Express also comes with built-in middleware and third-party middleware that you can use:
const express = require('express'); const app = express(); // Built-in middleware for parsing JSON and URL-encoded data app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Third-party middleware for handling CORS const cors = require('cors'); app.use(cors());
Error Handling
Express provides a way to handle errors using middleware. You can create an error-handling middleware with four arguments (err, req, res, next):
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!'); });
Working with Databases
Express doesn't come with a built-in database integration, but it's easy to use with various databases. Here's an example using MongoDB with Mongoose:
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/myapp', { useNewUrlParser: true, useUnifiedTopology: true }); const User = mongoose.model('User', { name: String, email: String }); app.post('/users', async (req, res) => { try { const user = new User(req.body); await user.save(); res.status(201).send(user); } catch (error) { res.status(400).send(error); } });
RESTful API Design
Express is great for building RESTful APIs. Here's a basic structure for a RESTful user resource:
const router = express.Router(); router.get('/users', getUsers); router.get('/users/:id', getUser); router.post('/users', createUser); router.put('/users/:id', updateUser); router.delete('/users/:id', deleteUser); app.use('/api', router);
Template Engines
For rendering dynamic content, Express can be used with various template engines. Here's an example using EJS:
app.set('view engine', 'ejs'); app.get('/profile', (req, res) => { res.render('profile', { name: 'John Doe', age: 30 }); });
Conclusion
Express.js provides a solid foundation for building web applications and APIs. Its flexibility allows developers to structure their applications according to their needs, while its extensive ecosystem of middleware and plugins makes it easy to add functionality as required.