Full Stack LAMP - MEAN Developer, Python developer. Certified Azure Developer. Freelance programmer/consultant/trainer.

Building REST APIs with ES6, Node.js, Express, and MongoDB

In this tutorial, we will use ES6 syntax to build REST APIs. we will set up Babel to work with ES6 and we’ll be building a RESTful CRUD (Create, Retrieve, Update, Delete) API with Node.js, Express, and MongoDB. We’ll use Mongoose for interacting with the MongoDB instance.

Creating the Application

Fire up your terminal and create a new folder for the application

$ mkdir todo-app

Initialize the application with a package.json file

$ npm init --yes

Install dependencies

npm i express body-parser mongoose

Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
body-parser: Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
mongoose is the ORM, will use to interact with MongoDB.

Install dev dependencies

npm i -D nodemon babel-cli bable-preset-env

nodemon: will restart the server whenever we change something in our code.
babel-preset-env: will install the presets es2015, es2016, es2017 along with some other(http://babeljs.io/docs/plugins/#presets).
babel-cli: will compile files to garget JavaScript version.

After successful installaiton, your package.json file content might look like below package.json file.

{
  "name": "express-babel",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start":"nodemon ./server.js --exec babel-node --presets babel-preset-env"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.2",
    "express": "^4.16.2",
    "mongoose": "^5.0.6"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-preset-env": "^1.6.1",
    "nodemon": "^1.15.0"
  }
}

All set, now let’s define folder structure for the app, create following folders and files –

src/controllers/downloadController.js
src/models/downloadModel.js
src/routes/downloadRoutes.js
server.js

The server.js file is the main file, here in this file we are creating HTTP server and connecting to MongoDB.

import express from 'express'
import routes from './src/routes/downloadRoutes'
import mongoose from 'mongoose'
import bodyParser from 'body-parser'

const app = express()
const PORT = 3000

mongoose.Promise = global.Promise;
mongoose.connect('mongodb://user:password@ds239648.mlab.com:39648/db_name')

app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json());

routes(app)

app.listen(PORT, () => {
    console.log(`you are server is running on ${PORT}`);
})

Let’s define download model, which contains two fields called fileName and path.

import mongoose from 'mongoose'

const Schema = mongoose.Schema

const DownloadSchema = new Schema({
    fileName: {
        type: String,
        required: 'File Name required'
    },
    path: {
        type: String,
        required: 'path is required.'
    }
})

export default DownloadSchema;

Let’s update your downloadController.js file with the following code, the code is pretty straightforward if you have any doubts drop a comment.

import mongoose from 'mongoose'
import downloadSchema from '../models/downloadModel'

const Download = mongoose.model('Download', downloadSchema)

// add new download to the database
export function addNewDownload(req, res) {
    let newDownload = new Download(req.body)
    newDownload.save((error, download) => {
        if (error) { res.json(error) }
        res.json(download)
    })
}

// get all downloads from the database
export function getDownloads(req, res) {
    Download.find({}, (error, downloads) => {
        if (error) { res.json(error) }
        res.json(downloads)
    })
}

// get single download based on the id
export function getDownload(req, res) {
    Download.findById(req.params.id, (error, download) => {
        if (error) { res.json(error) }
        res.json(download)
    })
}

// update the download information based on id
export function updateDownload(req, res) {
    Download.findOneAndUpdate({ _id: req.params.id }, req.body, { new: true }, (error, download) => {
        if (error) { res.json(error) }
        res.json(download)
    })
}

// delete the download from the database.
export function deleteDownload(req, res) {
    Download.remove({ _id: req.params.id }, (error, download) => {
        if (error) { res.json(error) }
        res.json(download)
    })
}

Final setup define route for each controller method. Here is downloadRoutes.js file.

import { addNewDownload, getDownloads, getDownload, updateDownload, deleteDownload } from '../controllers/downloadController'

const routes = (app) => {
    app.route('/download')
        .get(getDownloads)
        .post(addNewDownload)

    app.route('/download/:id')
        .get(getDownload)
        .put(updateDownload)
        .delete(deleteDownload)
}

export default routes

How to test

You can use any REST client like advacnedREST client or postman ..etc. You can also use CURL, here you go…

$ curl -H 'content-type: application/json' -v -X GET http://localhost:3000/download 
$ curl -H 'content-type: application/json' -v -X GET http://localhost:3000/download/:id
$ curl -H 'content-type: application/json' -v -X POST -d '{"fileName":"Test api","path":"/var/www/html/downloads/test.jpg"}' http://localhost:3000/download
$ curl -H 'content-type: application/json' -v -X PUT -d '{"fileName":"Test All APIs","path":"/var/www/html/downloads/test-2.jpg"}}' http://localhost:3000/download/:id
$ curl -H 'content-type: application/json' -v -X DELETE http://localhost:3000/download/:id

Leave a Reply