Last updated on November 17, 2022
By reading this tutorial you can build RESTful APIs using Node, express, and sequelize ORM. You gonna use the different HTTP methods during the REST API development, quick introduction to each method.
GET to retrieve data
POST to add data
PUT to update data
DELETE to delete data
Each method has a purpose, isn’t it? Let me give an introduction to the app which you are going to build is the TODO application. You can add a todo list, update, delete todos and you can even search for todos.
You can read the async and await version of this post at – RESTful API Using async, await – Node, Express and sequelize
You are going to build the following endpoints:
Method | URL | Action |
---|---|---|
GET | /todos | Retrieve all todos |
GET | /todos/search/bug | Search for todos with ‘bug’ in their name |
GET | /todo/1 | Retrieve todo with id == 1 |
POST | /todo | Add a new todo |
PUT | /todo/1 | Update todo with id == 1 |
DELETE | /todo/1 | Delete todo with id == 1 |
Install sequelize-cli and express-generator
Following npm command installs sequelize-cli
and express-generator
globally. It means you can access it from anywhere via the terminal.
npm install -g sequelize-cli express-generator
Project setup
Lets create an Express app named "todos-manager"
with express generator. With following command, the app will be created in a folder named todos-manager
in the current working directory and the view engine will be set to Pug
:
$ express --view=pug todos-manager
create : todos-manager
create : todos-manager/package.json
create : todos-manager/app.js
create : todos-manager/public
create : todos-manager/routes
create : todos-manager/routes/index.js
create : todos-manager/routes/users.js
create : todos-manager/views
create : todos-manager/views/index.pug
create : todos-manager/views/layout.pug
create : todos-manager/views/error.pug
create : todos-manager/bin
create : todos-manager/bin/www
create : todos-manager/public/javascripts
create : todos-manager/public/images
create : todos-manager/public/stylesheets
create : todos-manager/public/stylesheets/style.css
install dependencies:
$ cd todos-manager && npm install
run the app:
$ DEBUG=todos-manager:* npm start
After generating code, your folder structure should be similar to below shown
Install sequelize
Sequelize is an easy-to-use multi-SQL dialect ORM for Node.js. We gonna use MySQL as our database.So let install Sequelize ORM and mysql2 dialect.
$ cd todos-manager && npm install
$ npm install --save sequelize
$ npm install --save mysql2
Initializes sequelize
After installation, let’s use the CLI to generate migrations, seeders, config, model directories, and config files.
$ sequelize init // final, Initializes project with sequelize cil
I got following log in my console:
Sequelize [Node: 7.4.0, CLI: 2.5.1, ORM: 4.10.0]
Created "config\config.json"
Successfully created migrations folder at "C:\Users\arjun\Desktop\arjunphp\node-express-restful\migrations".
Successfully created seeders folder at "C:\Users\arjun\Desktop\arjunphp\node-express-restful\seeders".
Successfully created models folder at "C:\Users\arjun\Desktop\arjunphp\node-express-restful\models".
Loaded configuration file "config\config.json".
Using environment "development".
After executing sequelize init
command, your folder structure should be similar to below shown
If you are windows user correct the config file path in models/index.js
by changing
to
var config = require(__dirname + '/..\config\config.json')[env];var config = require(__dirname + '/../config/config.json')[env];
Database Configurations
Now config.json
file which is located at config\config.json
and update your database details,
{
"development": {
"username": "root",
"password": "",
"database": "arjunphp_node_rest",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
.......
.......
},
"production": {
.......
.......
}
}
Create Models and Migrations
Now again we gonna use sequelize cli command to generate model and migrations files.
sequelize model:create --name Todo --attributes title:string,description:string
The above command generates a todo.js
file in the PROJECT_ROOT/models
folder as well as a -create-todo.js
migration file in the PROJECT_ROOT/migrations
folder. will be the date the model was generated.
PROJECT_ROOT/models/todo.js
Here is the generated model code, you can add or remove columns to it, make sure to update the migration file for your changes on this model.
'use strict';
module.exports = function(sequelize, DataTypes) {
var Todo = sequelize.define('Todo', {
title: DataTypes.STRING,
description: DataTypes.STRING
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return Todo;
};
PROJECT_ROOT/migrations/20170921180639-create-todo.js
Here is the generated migration code, you can add or remove columns to it, make sure to update the model file for your changes on this migration file.
'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('Todos', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING
},
description: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('Todos');
}
};
Run Migrations
You can create database tables by running migrations with:
sequelize db:migrate
That’s it, now you can check your database, and you should able to see new tables in your database.
Implementing the API calls with Express
Routes
Let’s create a file called todos.js
in routes
directory with following code:
var express = require('express');
var router = express.Router();
var model = require('../models/index');
/* GET todo listing. */
router.get('/', function(req, res, next) {
});
/* POST todo. */
router.post('/', function(req, res, next) {
});
/* update todo. */
router.put('/:id', function(req, res, next) {
});
/* GET todo listing. */
router.delete('/:id', function(req, res, next) {
});
module.exports = router;
Now require todos.js
file inside the app.js
file just like other route files.
.............
..................
.........
var index = require('./routes/index');
var users = require('./routes/users');
var todos = require('./routes/todos');
.............
..................
.........
app.use('/', index);
app.use('/users', users);
app.use('/todos', todos);
.............
..................
.........
List of todos
Lets write a api call to get list of todos, Open your todos.js
file and update the get method with the following code.
/* GET todo listing. */
router.get('/', function (req, res, next) {
model.Todo.findAll({})
.then(todos => res.json({
error: false,
data: todos
}))
.catch(error => res.json({
error: true,
data: [],
error: error
}));
});
Test the request out in the browser – http://localhost:3000/todos
. You will get an empty array in your todos table is empty, if you have data in the todos table, you will get data in JSON format.
Creating a todo
Let’s make a post request to make a todo entry in the database,
/* POST todo. */
router.post('/', function (req, res, next) {
const {
title,
description
} = req.body;
model.Todo.create({
title: title,
description: description
})
.then(todo => res.status(201).json({
error: false,
data: todo,
message: 'New todo has been created.'
}))
.catch(error => res.json({
error: true,
data: [],
error: error
}));
});
You can test with any rest client tools like Advanced REST client, or Postman, but I am going to use Curl.
curl --data "title=create a rest client&description=create it with node js" http://localhost:3000/todos
Updating a todo
router.put('/:id', function (req, res, next) {
const todo_id = req.params.id;
const { title, description } = req.body;
model.Todo.update({
title: title,
description: description
}, {
where: {
id: todo_id
}
})
.then(todo => res.json({
error: false,
message: 'todo has been updated.'
}))
.catch(error => res.json({
error: true,
error: error
}));
});
To test issue following command,
curl -X PUT -H "Content-Type: application/json" -d '{"title":"create a rest client","description":"create it with node js"}' "http://localhost:3000/todos/1"
Deleting a todo
/* Delete todo. */
router.delete('/:id', function (req, res, next) {
const todo_id = req.params.id;
model.Todo.destroy({ where: {
id: todo_id
}})
.then(status => res.json({
error: false,
message: 'todo has been delete.'
}))
.catch(error => res.json({
error: true,
error: error
}));
});
To test issue following command,
curl -X "DELETE" http://localhost:3000/todos/1