What is Express?
Express is a web framework. It provides a very minimalist structure to build web applications. Express shares the same spirit as NodeJs. Express is unopinionated, fast and small. This framework doesn’t force you down a certain path. It only gives you a solid foundation to build upon. This is why Express is a very popular tool in the community. In this article, I will show you a extremely simple Express application. Nothing crazy. It will contain a single file that will help you have something up and running in no time. Then, I will show you the Express generator that creates a full skeleton of a Express application. Let’s get started.
Install and Run
Let’s create a directory called simple-express-app. In this directory, create a single file called index.js.
The first thing we want to do is install Express globally. To do so, open your terminal and enter this command:
npm install -g express
Note: you may have to use sudo for this command.
Great, now open your index.js:
Explanation: we import express in the first line. Then, we instantiate a new Express application and store it in the variable app. This new Express instance allow us to use a lot of amazing methods on it. Here, because this is a simple example. We use the get method. This handles the HTTP GET requests to the specified path.
On line 4, we tell Express how to handle the GET requests made for our index page (‘/’). The callback function takes three parameters, a request, a response and next. You will often times see this abbreviated as req, res, next. We can access the request object thanks to req and control the way our response will be with the res object. The next function tells Express to call the next matching route. We will see it in use a bit later when we will use middlewares.
So, our index page is going to end the response by sending the string ‘Hey Home’.
On line 9, we handle the GET request at the /about path. This time, we decide to send a JSON response. Then, we need to tell our application which port it should listen to.
So if we run this application with:
node index.js
and then visit our http://localhost:3000/ , we see => ‘Hey Home’. If we go to http://localhost:3000/about , we get => {message: ‘About Page’} . Awesome!
Now, let’s go a bit deeper and use something called a middleware. As its name indicates, a middleware is something that is used in the middle. Let me show you a quick example by changing our index.js file like this:
We use middlewares in Express with the use method. Every time our application receives a request, but before we give control back to our other routes, we will run the middleware at line 4 (in the middle remember?). This way, we have a lot more control over our application and it prevents duplicate code. In this example, we log a string with the URL, the hostname and the method. Then, we tell our response object to display HTML in the browser when the status code is 200 (meaning everything is OK). I do not have to tell each route how to display its content, nor do I have to write the console.log statement everytime. Let’s run this file now.
If you visit the homepage or the about page, you will see the corresponding HTML and the log in the console. But, if you go to a path that we do not handle, /contact for example, you will still have the log in you console. Remember, the middleware is called before the response is emitted. Then, we call next(). Earlier, I said that next passes control to the next matching route. So, if I visit /about, when next() is called in our middleware, we run app.get(‘/about’ …. But, if I visit a page that we do not handle, our server will just hang … We could add a little piece of code after our routes like this one :
app.use('*', (req, res, next) => { res.end('Page not found'); });
If our server can’t find a matching route, we will just print out ‘Page not found’. Our first middleware will log our string and pass control to this new middleware if no path matches. The ‘*’ is a shortcut for all the routes.
Note: Make sure to add this middleware after all the other routes. Otherwise, you will always see ‘Page not found’.
Ok, we have a very simple Express application that allows you to understand a little bit what Express is about. We only scratch the surface here and it would be impossible to explore every Express possibility in one blog post. In the last section, we will see how the Express executable work.
Express Generator
The Express executable does a lot of good things for you. It creates a skeleton for your app and allows you to choose a template engine. Express provides support for a variety of different template engines. Those engines let’s you pass data to your view. It’s pretty much HTML on steroids. You can pass markup, data, add some logic … But, this is outside the scope of this article. You can have more info about the executable by tying the command:
express --help Usage: express [options] [dir] Options: -h, --help output usage information -V, --version output the version number -e, --ejs add ejs engine support (defaults to jade) --hbs add handlebars engine support -H, --hogan add hogan.js engine support -c, --cssadd stylesheet support (less|stylus|compass|sass) (defaults to plain css) --git add .gitignore -f, --force force on non-empty directory
In addition, you could specify a CSS preprocessor using the –css option, or enable session middleware with –sessions.
Ok, let’s just see what this thing does. I’ll just create a application called myApp and use the hogan template engine.
express -H myApp
And here is the result:
express -H myApp create : myApp create : myApp/package.json create : myApp/app.js create : myApp/public create : myApp/public/javascripts create : myApp/public/images create : myApp/public/stylesheets create : myApp/public/stylesheets/style.css create : myApp/routes create : myApp/routes/index.js create : myApp/routes/users.js create : myApp/views create : myApp/views/index.hjs create : myApp/views/error.hjs create : myApp/bin create : myApp/bin/www install dependencies: $ cd myApp && npm install run the app: $ DEBUG=myApp:* npm start
As you can now see, you have a shiny new directory with a nice application skeleton. You have to install the few dependencies that were generated and you are good to go! We won’t cover everything, but let’s just take a look at our entry point: app.js
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hjs'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); module.exports = app;
Alright, let’s break this down a bit. The first lines import all the dependencies. Then, we require the files responsible for our routes. you can use a Router with Express, to make it simpler to handle your routes. You can get more information here. Then, with the two app.set lines. We tell our application where our views are and which template engine we use (I chose Hogan for this). The next block serves as a configuration for our app. The bodyParser will allow your application to parse the request bodies for example. The logger will log friendly output in your console. The express.static middleware tells Express where to find your static files. Here, we will look in the public directory.
You can run this application with
npm start
and visit localhost:3000 .
Congratulations, you have now a solid skeleton for your future web applications! I highly encourage you to play around with the Express generator and see what each part does. Remember that this framework really doesn’t force you on any path. The generator only gives you some tools to improve your development process and a Router. You still have complete control over the tools you want to implement and the path you want to take.
Express is a really great tool to learn and explore all the possibilities of web development.
Have fun.
As always, feel free to share and ask questions.
Have a great day!