While it is possible to build web applications with just Node.js, it could be a bit tedious to do some of the necessary web development tasks. To make things easier, you can use a web framework that specifically exists for these types of tasks. In this topic, we'll look at the most popular web framework: Express. You will learn what Express is and why should you use it in development.
What is express.js?
Express.js is a lightweight, fast, and unopinionated web application framework for Node.js. It provides a robust set of features for building web applications and APIs that are single-page, multi-page, or hybrid. As part of the MEAN (MongoDB, Express.js, Angular.js, Node.js) stack, Express is a key tool in modern full-stack JavaScript development.
As you know, Node.js is a runtime environment that allows you to run JavaScript on the server side. It doesn't provide any specific tools for building web applications. That's where Express.js comes in. Express.js provides a layer of abstraction over Node.js, simplifying complex server-side programming tasks like routing, session management, and handling HTTP requests/responses. It also integrates well with other popular Node.js libraries and middleware, making it a popular choice for building web applications.
Why should you use it?
Express.js simplifies the process of building web applications by providing a simple and flexible API for designing these applications and APIs. It is designed to manage the basic functionality of a web server, allowing developers to focus on the unique features of their applications. Express.js provides a high degree of modularity by enabling developers to choose from a wide range of Node.js modules for various functionalities such as database integration, template engines, and session management.
Let's consider a scenario where you are building a simple API for a blog application using only Node.js. The API needs to handle CRUD (Create, Read, Update, Delete) operations for blog posts. You want to design a scalable and easy-to-maintain solution that can handle multiple routes while providing error-handling functionality.
With only Node.js, you can certainly build the API by writing custom code for handling HTTP requests, parsing request bodies, implementing routing logic, and managing error handling. However, building everything from scratch can be time-consuming and error-prone. You would need to handle various aspects of the application manually, such as request parsing, routing, and error handling. This approach might lead to code duplication and make the codebase harder to maintain as the application grows.
Using Express.js in this scenario allows you to leverage its features, such as routing, middleware support, and the rich ecosystem, to build a robust and scalable API quickly. It simplifies the development process, reduces code duplication, and provides a solid foundation for future enhancements and maintenance. In the next section, we talk about the features that make this process easier.
Features of express.js
-
Middleware: 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. These functions can execute any code, make changes to the request and the response objects, end the request-response cycle, as well as call the next middleware function in the stack. This allows you to manage everything from error handling to parsing request bodies. Here's an example of using middleware in Express.js:const express = require('express'); const app = express(); // Middleware function const logger = (req, res, next) => { console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`); next(); // Call the next middleware function }; app.use(logger); // Register the middleware app.get('/', (req, res) => { res.send('Hello, World!'); }); app.listen(3000, () => { console.log('Server started on port 3000'); }); -
Routing: Express.js provides a robust routing mechanism. Routes are the different paths or endpoints that your application responds to. For example, if you have a blog, you might have routes for creating a new post, viewing a post, deleting a post, and so on. Here's an example of defining routes in Express.js:
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('Hello, World!'); }); app.post('/users', (req, res) => { // Handle creating a new user }); app.put('/users/:id', (req, res) => { // Handle updating a user with a specific ID }); app.delete('/users/:id', (req, res) => { // Handle deleting a user with a specific ID }); app.listen(3000, () => { console.log('Server started on port 3000'); }); -
Template Engines: Express.js supports template engines. A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values and transforms the template into an HTML file sent to the client. This approach makes it easier to design complex HTML pages. Some popular template engines supported by Express.js are EJS, Pug (formerly Jade), and Handlebars. Here's an example of the EJS template engine in Express.js:
const express = require('express'); const app = express(); // Set the view engine to EJS app.set('view engine', 'ejs'); app.get('/', (req, res) => { const data = { name: 'John Doe', age: 30, city: 'New York' }; res.render('index', { data }); // Render the 'index' template with data }); app.listen(3000, () => { console.log('Server started on port 3000'); }); -
Easy configuration and customization: Express.js is quite flexible. You can choose any of several settings to control various features of your Express application. For example, you can choose the template engine you want to use, specify a directory for static files, set the port for your application, and more.
-
Error handling: Express.js provides a built-in mechanism for error handling, simplifying the process of catching and managing errors in your applications. Here's an example of error handling:
app.use((req, res) => { res.status(404).send("404: Page not found"); });
The unopinionated nature of express.js
When people say that Express.js is "unopinionated", it means that Express doesn't force you to use any specific tools or follow any particular project structure. It provides the basic tools you need to build a web application but leaves many decisions up to the developer.
For example, Express.js doesn't come with a built-in ORM (Object-Relational Mapping) tool or database integration. You're free to choose whichever database or ORM you prefer. You can use MySQL, PostgreSQL, MongoDB, or any other database that suits your needs.
Similarly, Express.js doesn't impose a specific structure for your application. You can structure your project as you see fit, whether that's MVC (Model-View-Controller), MVVM (Model-View-ViewModel), or some other pattern.
This "unopinionated" nature gives you a lot of flexibility, but it also comes with more responsibility. You have to make more decisions about your tech stack and project structure while ensuring that all the different parts of your application work well together. This can be a bit daunting for beginners, but it also makes Express.js a very customizable tool for building web applications.
Now let's look at some of the advantages of Express.
Advantages of express.js
-
Simplicity: Express.js makes it easy to define routes and respond to HTTP requests with simple syntax.
-
Performance: Being built on Node.js, Express.js shares its performance characteristics. The event-driven, non-blocking I/O model of Node.js makes Express.js applications very efficient.
-
Flexibility: Express.js does not enforce any specific way of doing things, giving developers a lot of flexibility in how they structure their applications.
-
Integration: Express.js can be easily integrated with various databases like MongoDB, MySQL, PostgreSQL, etc, making it easier to build data-driven applications.
-
Community Support: Express.js has a large and active community, which means you can find a wealth of tutorials, guides, and third-party middleware to help you with your project.
A simple express program
We'll look at creating an Express app in a later topic but if you have Node and npm installed you can quickly install Express with npm:
npm install express
After that, you can run the code below in a terminal with node to create a simple Express server:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
Here's how this code works:
const express = require('express');— This line imports the Express.js module.const app = express();— This line creates an instance of an Express.js application.const port = 3000;— This line sets the port number to 3000. This is the port where the server listens for incoming requests.app.get('/', (req, res) => { res.send('Hello World!'); });— This line sets up a route handler for HTTP GET requests made to the root path ('/'). When such a request is received, the server sends back the stringHello World!.app.listen(port, () => { console.log(Server is running at http://localhost:${port}`); });— This line starts the server, which listens for requests on the specified port. Once the server is running, it logs a message to the console.
The code snippet gives the following result:
Conclusion
In conclusion, Express.js is a flexible and minimalist web application framework for Node.js. Its simplicity, high performance, and ability to integrate with various databases and middleware make it a popular choice among developers. Whether you're building a simple website or a complex API, Express.js provides the tools and features you need to build robust, efficient, and maintainable web applications. It complements Node.js by filling in the gaps in its functionality, providing a layer of abstraction that simplifies many common web development tasks. With a large and active community, there are plenty of resources available to help you learn and master Express.js.