Leveraging Sequelize and Other ORMs in JavaScript

Zack Kelly
4 min readMay 30, 2021

Having a presence on the web is more important now then ever before, and just about every professional and commercial entity has some sort of web application. While these apps can vary wildly in their scope and purpose, there are some core structural building blocks that are shared by most of them: a front-end which controls what the user sees and interacts with, a database that stores any necessary information, and a back-end server which controls the flow of information to and from both of them.

ORM, or object relational mapping, is a programming technique that sees database entries stored as objects while being created, retrieved, or otherwise operated on within an app. In a somewhat confusing use of acronyms, this technique is usually implemented using ORMs, or object relational mappers: libraries that are available for many different programming languages and database structures.

Very simple example of information flow

Benefits

There are a number of benefits to using an ORM in your application, most prevalent of which is cleaner and more organized code. Without one, you will likely have files which contain, for example, JavaScript functions that implement SQL queries in a completely unrelated syntax. Using an ORM, these queries would be replaced with JavaScript object operations in a much more similar format to the rest of the code. This allows you to abstract the database language away from your code, much like abstracting CSS into stylesheets instead of having your styles declared at the top of your HTML documents/inline.

//Example of SQL queries mixed into JS a JS function
const addFavorite = (userID, listingID) => {
return db.query('INSERT INTO favorites(user_id, listing_id) VALUES($1, $2) RETURNING *;', [userID, listingID])
.then((response) => {
return response.rows;
});
};

The complete list of benefits may vary between individual ORMs, but there are some features that are common among most of them. Many include tools which will allow you to generate migrations or seeding files for your databases, saving time and reducing the chance of errors caused by typos or missing syntax. Many also use the concept of transactions, which batch together a series of operations into a single unit. When managing a series of operations like this manually, it can be very difficult to restore the state of the database were an error to occur part-way through. With transactions, you are more protected, and the database can be rolled back if the entire transaction does not complete successfully.

The ORM that you choose will depend on the language of your code and of your database in addition to the features you’re looking for. If you’re writing a Ruby on Rails app you might choose to use Active Record. If your database uses MongoDB, and your app is written in TypeScript, Typegoose is a good choice. There are a number of popular JavaScript ORMs including Bookshelf, Waterline, Mongoose, and Sequelize. The latter is what I will focus on for the remainder of this article, exploring how to get started using it to improve your app.

Sequelize

Installing Sequelize in a Node.JS app is about as easy as installing any other package thanks to npm, and you can get started using it with a simple require. There are a number of ways to actually connect to your database; I will show one postgres example here but the rest can be viewed in the Sequelize documentation linked at the bottom of the page.

npm install --save sequelize
----------
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname')

From there, you can create a model and specify attributes and constraints, again with multiple syntaxes being available. In this case, we are declaring the name field to be a string, and not allowing null(blank) entries.

const Patient = sequelize.define('Patient', {
name: {
type: DataTypes.STRING,
allowNull: false
}
});
(async () => {
await sequelize.sync({ force: true });
})();

The last block in the above example is important because creating the object model by itself has no impact on the actual database. Using sync, the database will be updated with the model, and using similar syntax we can create and save instances of this new object type.

const john = Patient.build({ name: "John Doe"});
await john.save();

Again, the save is important here to actually update the database with this new patient, which will likely be represented by a row in a patients table.

We have only begun to scratch the surface of what you can do with Sequelize, and I am still diving into it myself. If your app contains anything more than the most minimal usage of data, I encourage you to look into the world of ORMs and try one out if you haven’t already. There’s a good chance that they will make your life easier, and your team and your app will thank you for a cleaner, more organized, and more readable codebase.

--

--