Best Practices for Structuring Express Apps

John Au-Yeung
May 5, 2020 · 4 min read
Photo by Jack Catalano on Unsplash

Express is a Node.js web framework that’s used to write back end apps. It has a very small core and allows for lots of flexibility. Therefore, it’s a good idea to establish some best practices.

In this article, we’ll look at some best practices for structuring our Express projects.

Model-View-Controller (MVC) Design Pattern

We can organize our Express app however we want. But the most common and convention way to organize our app is with the MVC pattern.

It compartmentalizes our app into chunks that does various things. The model lets us access data. The views display data to the user and accept input. The controller acts as a bridge between the model and the view.

We can organize the code with the following directories to separate the code into logical pieces:

  • controllers/ — holds the app routes and logic

Models

Models are where data access and manipulation happens. They contain the functions which handle our data, which includes code for creating, reading, updating, and deleting items.

It also contains business logic.

We should create at least one file for each type of data in our database. For instance, if we have posts and comments, we should have model file for post and another one for comment .

Then we can add our logic inside our model as methods of the model class stored in each file.

They should be independent of the outside world. Therefore, they should never receive request or response objects. This makes it easy to isolate and test. Also, they should never return HTTP errors, but they should return model-specific errors.

A simple model file may have the following code:

const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database(':memory:');
db.run("CREATE TABLE IF NOT EXISTS posts (content TEXT)");
const createPost = (content) => {
db.serialize(() => {
const stmt = db.prepare("INSERT INTO posts VALUES (?)");
stmt.run(content);
stmt.finalize();
});
db.close();
}

The code above uses sqlite3 to access our in-memory database and has a function to insert values into our posts table.

Views

Views lets users view the content of our app and take in the input. Common templating systems that work with Express include Jade and Mustache.

They take data from the controller and display them, and we can also get inputs from them. For instance, we can render data from the controller to a template as follows:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'pug')
app.get('/', (req, res) => {
res.render('index', { title: 'Hey', message: 'Hello there!' });
});
app.listen(3000, () => console.log('server started'));

views/index.pug :

html
head
title= title
body
h1= message

Then we get the message ‘Hello there!’ displayed on the screen and the title of the page is ‘Hey’.

Photo by Karlijn Prot on Unsplash

Controllers

Controllers are where we’ll defining all the routes that our app will serve. Controllers handle web requests, serve templates, and interact with models to get and manipulate data.

Routes in the same controller should start with the same prefix. If we have a controller for posts , then we may have the /posts/all and /posts/new route, for example.

We can define an Express controller as follows:

const express = require('express');
const bodyParser = require('body-parser');
const router = express.Router();
const app = express();
router.get('/all', (req, res) => {
res.json([
//...
]);
});
router.post('/new', (req, res) => {
res.send('post added');
});
module.exports = router;

In the code above, we have the router object, which is created by express.Router . Then we can include adding routes to our Express app object as follows:

const express = require('express');
const bodyParser = require('body-parser');
const router = express.Router();
const app = express();
const posts = require('./posts');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/posts', posts)
app.listen(3000, () => console.log('server started'));

We imported the posts file from above and then called app.use to include the file we imported in our app.

Express Generator

To create a new Express project that has this structure, we can use the Express Generator Node package. We can use it by running:

npx express-generator

Conclusion

The model-view-controller pattern is the most important and common pattern for organizing back end apps. This helps us separate our code into a group of files with routes, another group with views, and another one with our data access and business logic code.

With Express, we can organize the code files ourselves or we can use the Express Generator Node package to create a new project with this structure.

The Startup

Get smarter at building your thing. Join The Startup’s +793K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at https://thewebdev.info/subscribe/. Email me at hohanga@gmail.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +793K followers.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at https://thewebdev.info/subscribe/. Email me at hohanga@gmail.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +793K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store