DEV Community

Robert
Robert

Posted on • Updated on

Node Express REST API tutorial

Node-Express-rest-api-tutorial

In the following example will be creating a simple REST API with node and express.

You can contact me by telegram if you need to hire a Full Stack developer..

Creating our project

  • open your terminal and type the following
  • mkdir node-express-rest-api-tut
  • cd node-express-rest-api-tut
  • npm init --y
  • code .

Packages

  • express
  • mongoose
  • nodemon

Production packages

npm i express mongoose
Enter fullscreen mode Exit fullscreen mode

Development packages

npm i nodemon -D
Enter fullscreen mode Exit fullscreen mode

project file structure:

node-express-rest-api-tut/
├── node_modules/
├── src/
│ ├── controllers/
│ ├── routes/
│ ├── models/
│ └── index.js
└── package.json

Project setup

 "scripts": {
    "dev": "nodemon src/index.js"
  },
Enter fullscreen mode Exit fullscreen mode

Let's code.

Creating our index.js
index.js

const express = require('express')

const app = express()

//middlewares
app.use(express.json())

//server
app.listen(3000, () => {
  console.log('listening on port 3000')
})
Enter fullscreen mode Exit fullscreen mode

Now let's run npm run dev and we should get this:
listening on port 3000.

Go to db.js to configure our connection to the database.

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/contacts')
  .then(() => console.log('Connected to MongoDB...'))
  .catch(err => console.error('Could not connect to MongoDB...', err));
Enter fullscreen mode Exit fullscreen mode

Go back to our index.js and require or db connection.

index.js

const express = require('express')
require('./db')

const app = express()

//middlewares
app.use(express.json())

//server
app.listen(3000, () => {
  console.log('listening on port 3000')
})
Enter fullscreen mode Exit fullscreen mode

Now let's run npm run dev and we should get this:

listening on port 3000 
Connected to MongoDB...
Enter fullscreen mode Exit fullscreen mode

Let's go to our routes folder and create this file contacts.route.js, we are going to create 5 routes, and for the moment the routes are only going to respond with a message.

contacts.route.js

const { Router } = require('express')

const route = Router()

//get all contacts
router.get('/', (req, res) => {
  res.send('contacts list')
})

//create a contact
router.post('/', (req, res) => {
  res.send('contacts list')
})

//get a contact by id paramater
router.get('/:id', (req, res) => {
  res.send('contacts list')
})

//delete a contact
router.delete('/:id', (req, res) => {
  res.send('contacts list')
})

//edit a contact
router.put('/:id', (req, res) => {
  res.send('contacts list')
})

export default route
Enter fullscreen mode Exit fullscreen mode

Let's go back to index.js and require our contacts.route.js module.

index.js

const express = require('express')
require('./db')
const contactsRoute = require('./routes/contacts.route')

const app = express()

//middlewares
app.use(express.json())

//server
app.listen(3000, () => {
  console.log('listening on port 3000')
})
Enter fullscreen mode Exit fullscreen mode

Let's test our routes, I am going to use VScode REST client extension, but feel free to use whatever you want.

apitest

To make our code cleaner let's go to controllers folder and create contacts.controller.js file, in this file we are going to create our routes functions, first create an object that I'm going to name contactController, then going to create a method named getContacts.

contacts.controller.js

contactsController = {}

contactsController.getContacts = 

module.exports = contactsController
Enter fullscreen mode Exit fullscreen mode

Let's see the first route of contacts.route.js.

contacts.route.js

const { Router } = require('express')

const route = Router()

//get all contacts
router.get('/', (req, res) => {
  res.send('contacts list')
})

.
.
.

Enter fullscreen mode Exit fullscreen mode

Let's pass the function of this route to our controller.

contacts.controller.js

contactsController = {}

contactsController.getContacts = (req, res) => {
  res.send('contacts list')
}

module.exports = contactsController
Enter fullscreen mode Exit fullscreen mode

And now replace the route function with the controller like this.

contacts.route.js

const { Router } = require('express')
const { getContacts } = require('../controllers/contacts.controller')

const route = Router()

//get all contacts
router.get('/', getContacts)

.
.
.

Enter fullscreen mode Exit fullscreen mode

If we test our route the result will be the same, so let's do the rest of the controllers.

contacts.controller.js

contactsController = {}

contactsController.getContacts = (req, res) => {
  res.send('contacts list')
}
contactsController.createContact = (req, res) => {
  res.send('create contact')
}
contactsController.deleteContact = (req, res) => {
  res.send('delete contact')
}
contactsController.getContactById = (req, res) => {
  res.send('get contact')
}
contactsController.editContact = (req, res) => {
  res.send('update contact')
}

module.exports = contactsController
Enter fullscreen mode Exit fullscreen mode

contacts.route.js

const {Router} = require('express')
const { getContacts, getContactById, createContact, deleteContact, editContact } = require('../controllers/contacts.controller')

const router = Router()

router.get('/', getContacts)
router.post('/', createContact)
router.get('/:id', getContactById)
router.delete('/:id', deleteContact)
router.put('/:id', editContact)

module.exports = router
Enter fullscreen mode Exit fullscreen mode

Let's go to our models folder and create ContactModel.js file, lets use some fields for our contact, (first name, last name, a phone number and a email address).

ContactModel.js

const mongoose = require('mongoose')

const ContactSchema = mongoose.Schema({
  firstName: {
    type: String,
    required: true,
  },
  lastName: {
    type: String,
    required: true,
  },
  phone: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
}, {timestamps: true})

module.exports = mongoose.model('Contact', ContactSchema)
Enter fullscreen mode Exit fullscreen mode

Now we are going to create our controllers functions to interact with the database, open the contacts.controller.js file, first lets import our ContactModel file.

contacts.controller.js

contactsController = {}
const ContactModel = require('../models/ContactModel')
.
.
.
Enter fullscreen mode Exit fullscreen mode

-Head to our first method getContacts, as we will make a request to the database it is going to take some time, so we will use async in our function, we will use the find() method to fetch all the contacts it finds, and we will handle it with a try/catch block so that we can receive error messages in case there are any.

contacts.controller.js

contactsController.getContacts = async (req, res) => {
  const contacts = await ContactModel.find()
  try {
    res.json({contacts})
  } catch (error) {
    res.status(500).json({error})
  }
}
Enter fullscreen mode Exit fullscreen mode

-Now go to createContact, in our model we specify the data we require for our contact, and create a new "model", if all goes well it will be stored in our database. In this example it will respond with the contact that was saved.

contacts.controller.js

contactsController.createContact = async(req, res) => {
  const contact = new ContactModel(req.body)
  try {
    await contact.save()
    res.json({contact})
  } catch (error) {
    res.status(500).json({error})
  }
}
Enter fullscreen mode Exit fullscreen mode

-Next one is getContactById, we will be working with a route like this http://localhost:3000/contacts/:id, where :id is the parameter we will be using to find the contact with that id.

We will use the findById() method to return the contact, if no contact is found it will return a contact not found message.

contacts.controller.js

contactsController.getContactById = async (req, res) => {
  const contact = await ContactModel.findById(req.params.id)

  if (contact == null) return res.json({message: 'Contact not found'})

  try {
    res.json({contact})
  } catch (error) {
    res.status(500).json({error})
  }
}
Enter fullscreen mode Exit fullscreen mode

-Next one is deleteContact, as in the previous case, we need the id, we will use the findByIdAndDelete() method, if it does not find a contact with that id it will return a message that it was not found, if it is found it will be deleted.

contacts.controller.js

contactsController.deleteContact = async (req, res) => {
  try {
    const contact = await ContactModel.findByIdAndDelete(req.params.id)

    if (contact == null) return res.json({message: 'Contact not found'})

    res.json({message: 'Contact deleted'})
  } catch (error) {
    res.status(500).json({message: 'contact not found'})
  }
}
Enter fullscreen mode Exit fullscreen mode

-Finally editContact, for this case we will use findIdAndUpdate() we need to pass the id to find the contact that we want to edit/update, then the new body, and finally the option {new: true} to return the edited contact, otherwise it will return the contact before editing it.

contacts.controller.js

contactsController.editContact = async (req, res) => {
  const contact = await ContactModel.findByIdAndUpdate(req.params.id, req.body, {new: true})
  try {
    res.json({contact})
  } catch (error) {
    res.status(500).json({error})
  }
}
Enter fullscreen mode Exit fullscreen mode

This is what our final file should look like.

contacts.controller.js

contactsController = {}
const ContactModel = require('../models/ContactModel')

contactsController.getContacts = async (req, res) => {
  const contacts = await ContactModel.find()
  try {
    res.json({contacts})
  } catch (error) {
    res.status(500).json({error})
  }
}

contactsController.createContact = async(req, res) => {
  const contact = new ContactModel(req.body)
  try {
    await contact.save()
    res.json({contact})
  } catch (error) {
    res.status(500).json({error})
  }
}

contactsController.deleteContact = async (req, res) => {
  try {
    const contact = await ContactModel.findByIdAndDelete(req.params.id)

    if (contact == null) return res.json({message: 'Contact not found'})

    res.json({message: 'Contact deleted'})
  } catch (error) {
    res.status(500).json({message: 'contact not found'})
  }
}

contactsController.getContactById = async (req, res) => {
  const contact = await ContactModel.findById(req.params.id)

  if (contact == null) return res.json({message: 'Contact not found'})

  try {
    res.json({contact})
  } catch (error) {
    res.status(500).json({error})
  }
}

contactsController.editContact = async (req, res) => {
  const contact = await ContactModel.findByIdAndUpdate(req.params.id, req.body, {new: false})
  try {
    res.json({contact})
  } catch (error) {
    res.status(500).json({error})
  }
}

module.exports = contactsController
Enter fullscreen mode Exit fullscreen mode

I hope you find this post helpful. please let me know what you think, thank you.

Top comments (0)