Sails Tutorial — Chapter 3

Kiran Chauhan
4 min readJun 21, 2024

This is the third article in the series. You can read the second one at this link.

Note: To follow this article, you need to install an API client to test the routes that we’re going to create in this article. Try Postman or Insomnia if you haven’t one.

In this article, we’re going to create the APIs for the Contact resource. If you’re building an MVC web app, then you need to create seven routes whereas if you’re creating an API web app, you need to create five routes.

To start with, let’s add a route that returns all the contacts as GET /contacts. When this route is requested, the server should run the index action of ContactsController in the config/routes.js file.

module.exports.routes = {
'GET /': 'HomeController.index',

// Contacts
'GET /contacts': 'ContactsController.index',
};

We don’t have this ContactsController.js file yet! Let’s create one in the api/controllers folder.

touch api/controllers/ContactsController.js

Open this ContactsController.js file and write the following code.

module.exports = {
index: (req, res) => {
res.json({ message: 'All contacts' });
},
};

Open the http://localhost:1337/contacts in the browser and you should see this JSON response.

Now, we need to add a route for a specific contact as GET /contacts/:id. When this route is requested, the server should run the show action of ContactsController in routes.js file.

module.exports.routes = {
'GET /': 'HomeController.index',

// Contacts
'GET /contacts': 'ContactsController.index',
'GET /contacts/:id': 'ContactsController.show',
};

Let’s define this show action within ContactsController.js file and also print the passed id value using req.params.id.

module.exports = {
index: (req, res) => {
res.json({ message: 'All contacts' });
},

show: (req, res) => {
console.log(`contact id is ${req.params.id}`);
res.json({ message: 'Single contact' });
},
};

Open the http://localhost:1337/contacts/1 in the browser and you should see this JSON response. You should also see the console message as contact id is 1 in the terminal.

Next, we need to add a route that creates a new contact by passing first name and last name as firstName and lastName respectively. We can define this route as POST /contacts and map against the create action of ContactsController.

module.exports.routes = {
'GET /': 'HomeController.index',

// Contacts
'GET /contacts': 'ContactsController.index',
'GET /contacts/:id': 'ContactsController.show',
'POST /contacts': 'ContactsController.create',
};

Let’s define this create action within ContactsController.js file and also print the passed firstName and lastName values using req.body.firstName and req.body.lastName (you can destructure in single line, if you want).

module.exports = {
index: (req, res) => {
res.json({ message: 'All contacts' });
},

show: (req, res) => {
console.log(`contact id is ${req.params.id}`);
res.json({ message: 'Single contact' });
},

create: (req, res) => {
console.log(`first name is ${req.body.firstName}`);
console.log(`last name is ${req.body.lastName}`);
res.json({ message: 'Creating contact' });
},
};

To test this route, we need to do a POST api call in Insomnia (or any other API client you’re using). You should get the above JSON response when calling this route and first name & last name should be consoled in the terminal.

Before we go further and add routes for updating a resource, let’s do a status code modification in create route as 201 should be the status code when creating a resource. We know how to do it as we’re going to use Express’s .status() method.

module.exports = {
index: (req, res) => {
res.json({ message: 'All contacts' });
},

show: (req, res) => {
console.log(`contact id is ${req.params.id}`);
res.json({ message: 'Single contact' });
},

create: (req, res) => {
console.log(`first name is ${req.body.firstName}`);
console.log(`last name is ${req.body.lastName}`);
res.status(201);
res.json({ message: 'Creating contact' });
},
};

Looking much better! Just confirm in Insomnia that you should get 201 status code in response (You can chain .status() and .json() methods in single line, if you want).

Let’s define a route to update a specific contact as UPDATE /contacts/:id. When this route is requested, the server should run the update action of ContactsController.

module.exports.routes = {
'GET /': 'HomeController.index',

// Contacts
'GET /contacts': 'ContactsController.index',
'GET /contacts/:id': 'ContactsController.show',
'POST /contacts': 'ContactsController.create',
'PUT /contacts/:id': 'ContactsController.update',
};

Let’s define this update action within the ContactsController.js file. Let’s also print the id as req.params.id and passed firstName & lastName values as req.body.firstName and req.body.lastName (you can also destructure, if you want).

module.exports = {
index: (req, res) => {
res.json({ message: 'All contacts' });
},

show: (req, res) => {
console.log(`contact id is ${req.params.id}`);
res.json({ message: 'Single contact' });
},

create: (req, res) => {
console.log(`first name is ${req.body.firstName}`);
console.log(`last name is ${req.body.lastName}`);
res.status(201);
res.json({ message: 'Creating contact' });
},

update: (req, res) => {
console.log(`contact id is ${req.params.id}`);
console.log(`first name is ${req.body.firstName}`);
console.log(`last name is ${req.body.lastName}`);
res.json({ message: 'Updating contact' });
},
};

we need to test this route in Insomnia. You should get the above JSON response when calling this route and id, first name & last name should be consoled in the terminal.

Finally, we need to add a route that deletes a specific contact as DELETE /contacts/:id and should run the destroy action of ContactsController. delete is a reserved keyword in JavaScript. Due to this, we choose destroy as function name.

module.exports.routes = {
'GET /': 'HomeController.index',

// Contacts
'GET /contacts': 'ContactsController.index',
'GET /contacts/:id': 'ContactsController.show',
'POST /contacts': 'ContactsController.create',
'PUT /contacts/:id': 'ContactsController.update',
'DELETE /contacts/:id': 'ContactsController.destroy',
};

Let’s define this destroy action within ContactsController.js file and also print the id as req.params.id.

module.exports = {
index: (req, res) => {
res.json({ message: 'All contacts' });
},

show: (req, res) => {
console.log(`contact id is ${req.params.id}`);
res.json({ message: 'Single contact' });
},

create: (req, res) => {
console.log(`first name is ${req.body.firstName}`);
console.log(`last name is ${req.body.lastName}`);
res.status(201);
res.json({ message: 'Creating contact' });
},

update: (req, res) => {
console.log(`contact id is ${req.params.id}`);
console.log(`first name is ${req.body.firstName}`);
console.log(`last name is ${req.body.lastName}`);
res.json({ message: 'Updating contact' });
},

destroy: (req, res) => {
console.log(`contact id is ${req.params.id}`);
res.json({ message: 'Deleting contact' });
},
};

And now we’ve the stub end-points for the given resource e.g. Contact with best practice to create REST APIs.

Take a break and read the forth article in this series at this link.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Kiran Chauhan
Kiran Chauhan

Written by Kiran Chauhan

I design software with and for people.

No responses yet

Write a response