Node Express REST API tutorial
Tags: node, beginners, tutorial, javascript
Published: 2022-04-26 23:50:00

## 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.](https://t.me/rtagliajs).


## 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
```console
npm i express mongoose
```

### Development packages
```console
npm i nodemon -D
```

## project file structure:

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

## Project setup

```json
 "scripts": {
    "dev": "nodemon src/index.js"
  },
```

### Let's code.

Creating our index.js
`index.js`
```js
const express = require('express')

const app = express()

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

//server
app.listen(3000, () => {
  console.log('listening on port 3000')
})
```

Now let's run `npm run dev` and we should get this:
<code>listening on port 3000</code>.

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

```js
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));
```

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

`index.js`
```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')
})
```

Now let's run <code>npm run dev</code> and we should get this:
```console
listening on port 3000 
Connected to MongoDB...
```

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`
```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
```

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


`index.js`
```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')
})
```

Let's test our routes, I am going to use [VScode REST client extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client), but feel free to use whatever you want.

![apitest](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmjo7m0drne1s7zzqbgx.png)

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`
```js
contactsController = {}

contactsController.getContacts = 

module.exports = contactsController
```

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

`contacts.route.js`
```js
const { Router } = require('express')

const route = Router()

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

.
.
.

```

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

`contacts.controller.js`
```js
contactsController = {}

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

module.exports = contactsController
```

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

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

const route = Router()

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

.
.
.

```

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

`contacts.controller.js`
```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
```

`contacts.route.js`
```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
```

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`
```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)
```

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`
```js
contactsController = {}
const ContactModel = require('../models/ContactModel')
.
.
.
```

-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`
```js
contactsController.getContacts = async (req, res) => {
  const contacts = await ContactModel.find()
  try {
    res.json({contacts})
  } catch (error) {
    res.status(500).json({error})
  }
}
```

-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`
```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})
  }
}
```

-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`
```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})
  }
}
```

-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`
```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'})
  }
}
```

-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`
```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})
  }
}
```
This is what our final file should look like.

`contacts.controller.js`
```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
```

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