Introduction to Express.js with TypeScript: Key Features
In this article, we will explore what Express.js with TypeScript is, why itβs widely used, how to install it, and its key features with practical examples.
What is Express.js?
Express.js is a lightweight and powerful framework for Node.js that helps you build web applications and APIs quickly and efficiently. If youβre new to backend development, think of Express as a tool that simplifies how your server handles requests and responses. Its flexibility allows you to create anything from basic websites to advanced APIs for complex applications. With features for managing HTTP requests, middleware, and routing, itβs a must-have for scalable backend systems.
Why Use It?
- Simplicity: Easy to learn and configure.
- Speed: High performance due to its lightweight nature.
- Flexibility: Extendable functionalities via middleware.
- Community and Support: Large ecosystem and extensive documentation.
- Ideal for REST APIs: Perfect for building scalable and modular backends.
- Database Compatibility: Easily integrates with MongoDB, MySQL, PostgreSQL, and other databases.
Installation and Setup Express.js with TypeScript
To get started with Express, you need to have Node.js installed. Then, follow these steps:
1. Initialize the project
mkdir my-express-app
Navigate to the project directory:
cd my-express-app
Initialize a new Node.js project with a pre-configured package.json
file:
npm init -y
2. Install Express.js and TypeScript
To use Express with TypeScript, install the required packages:
npm install express @types/express typescript ts-node
Initialize TypeScript with the command:
npx tsc --init
This will create a TypeScript configuration file.
npm install express
3. Create a Basic Server Express.js with TypeScript
Create a file index.ts
and add the following code:
import express, { Request, Response } from 'express';
const app = express();
const PORT = 3000;
app.get('/', (req: Request, res: Response) => {
res.send('Hello, Express with TypeScript!');
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
Start the server with:
ts-node index.ts
Now open your browser at http://localhost:3000
to see the result.
Key Features of Express.js
1. Routing
Express allows easy management of routes for APIs and web pages.
Use Case: User API
To manage user information, we can create the following routes:
app.get('/users', (req: Request, res: Response) => {
res.json([{ id: 1, name: 'Mario' }, { id: 2, name: 'Luigi' }]);
});
app.get('/users/:id', (req: Request, res: Response) => {
res.json({ id: req.params.id, name: 'Mario' });
});
Accessing http://localhost:3000/users
will return a list of users.
2. Middleware
Middleware functions are executed during an HTTP request lifecycle. They can modify the request, response, or pass control to other functions. Express uses middleware for authentication, logging, data parsing, error handling, and more.
β οΈ Note: To ensure middleware execution, it is crucial to include next()
in both the middleware function and the endpoints being tracked. Example:
app.use((req: Request, res: Response, next: NextFunction) => {
console.log(`Request: ${req.method} ${req.url}`);
next();
});
To properly pass execution to middleware, use next()
in endpoints:
app.get('/users/:id', (req: Request, res: Response, next: NextFunction) => {
res.json({ id: req.params.id, name: 'Mario' });
next();
});
3. JSON and Data Parsing
Express makes it easy to handle incoming data, such as JSON sent from a client.
Use Case: Receiving JSON Data from a Client
If a client sends JSON data to a REST API, we can handle it with Express.
app.use(express.json()); // TypeScript automatically handles this
app.post('/data', (req: Request, res: Response) => {
console.log('Received data:', req.body);
res.send(`Received: ${JSON.stringify(req.body)}`);
});
Example client request using fetch
in JavaScript:
fetch('http://localhost:3000/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Mario', age: 30 })
})
.then(response => response.text())
.then(data => console.log(data));
This allows structured data exchange between client and server.
4. Static File Hosting
You can make static files like images, HTML, and CSS available. To do this, create a public
folder in the project’s root directory and place the files you want to expose inside it.
Use Case: Exposing an HTML Page
Create a public
folder and add an index.html
file inside it:
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Static Page</title>
</head>
<body>
<h1>Welcome to Express with TypeScript!</h1>
</body>
</html>
Set up Express to indicate the directory where the file is located:
app.use(express.static('public'));
Now, by visiting http://localhost:3000/index.html
, you will be able to see the static page.
5. Error Handling
Express makes it easy to handle custom errors. We can also create an endpoint that intentionally generates an error to test the error-handling middleware.
Use Case: Endpoint that Generates an Error
We can create an endpoint that simulates an error:
app.get('/data_with_error', (req: Request, res: Response) => {
throw new Error('Test error');
});
Use Case: Global Error Middleware
app.use((err: Error, req: Request, res: Response) => {
console.error(err.stack);
res.status(500).json({ message: 'Something went wrong!', error: err.message });
});
This middleware intercepts errors and prevents server crashes.
6. Connecting to a Database
Express does not include an ORM, but it can be easily integrated with MongoDB, PostgreSQL, and other databases.
Use Case: Connecting to MongoDB with Mongoose
To use MongoDB, install Mongoose:
npm install mongoose
Then, configure the connection:
import mongoose from 'mongoose';
mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('MongoDB Connected'))
.catch(err => console.error('MongoDB connection error:', err));
Now, you can define models and interact with the database directly in your Express backend.
Alternative Database Options
If you prefer an alternative approach, consider other ORM libraries:
- Sequelize: A great option for relational databases like PostgreSQL, MySQL, and SQLite.
- Knex.js: A flexible query builder supporting various SQL databases.
Example: Connecting to PostgreSQL with Sequelize:
import { Sequelize } from 'sequelize';
const sequelize = new Sequelize('postgres://user:password@localhost:5432/mydb');
sequelize.authenticate()
.then(() => console.log('PostgreSQL Connected'))
.catch(err => console.error('Error connecting to PostgreSQL:', err));
Choose the ORM or query builder that best suits your project.
Conclusion
This article is not an in-depth guide to Express.js but a general overview to help you quickly understand its added value and main functionalities. The goal is to give you a clear idea of what Express can do and how to start using it. For more details and advanced topics, refer to the additional resources below.
Additional Resources
- Official Express.js Documentation – The complete guide to using Express effectively.
- MDN Web Docs – HTTP Overview – Learn more about HTTP requests and responses.
- REST API Design Guidelines – A guide for designing well-structured RESTful APIs.
- Official Express.js GitHub Repository – Express source code with examples and community contributions.