How to Create a Simple RESTful API in Node.js
By: Marcus Siegel
Tags: Nodejs, API, Expressjs, Mongodb, Tutorial

Getting started

As I reach the end of my time as a student at Flatiron School, I can’t help but feel excited about all the doors my newfound coding skills can open. One of those doors is learning new languages and runtimes. Unfortunately, I’ve let my anticipation get the best of me by putting together this tutorial. Today, we will create a RESTful book list API (i.e. endpoints that will create a book, get/read a list of all books, get a particular book, delete a book, and update a book). I created a GitHub repo here for anyone who wants to follow along or build off of what we’ll make today.

First Steps

I presume that you already have your environment set up (i.e Node.js and MongoDB is installed).

If you’re not sure, run npm -v and mongo --version in your terminal. These commands will show you the version of NPM and MongoDB you have installed.

You likely have Node already installed on your machine, if not, follow this link to install it.

Once you have finished installing, let’s begin our journey with the following basic steps.

Open your terminal and follow along:

Create a Folder name bookListApi — mkdir bookListApi Navigate to the root of your newly created folder — cd bookListApi Create a package.json file — npm init

Package.json is a file that gives the necessary information to npm which allows it to identify the project as well as handle the project's dependencies.

npm init will prompt you to enter some information such as the app name, description, version, author, and keyword.

You should have something like this:

Type yes and hit enter to complete the creation of our package.json. Having completed these steps, your folder structure should look like this:

Create a file called server.js — touch server.js. With this, we will be writing the protocols to create our server.

Create a folder called api — mkdir api

Inside the api folder, create an additional three folders called models, routes, and controllers by running mkdir api/controllers api/models api/routes

Create bookListController.js in the api/controller folder, bookListRoutes.js in the routes folder, and bookListModel in the model folder —

touch api/controllers/bookListController.js api/models/bookListModel.js api/routes/bookListRoutes.js

Our folder structure should look like this now:

Server setup

We’ll need a little help getting our server up and running. Let’s install Express and Nodemon! Express will be used to create the server, and Nodemon will help us keep track of changes to our application by watching for changed files and automatically restarting the server.

npm install -g nodemon

npm install express

After you finish installing, your package.json file will be modified to have the two newly installed packages. Open the package.json file and add this task to the script:

“start”: “nodemon server.js”

Open the server.js file and copy/paste the code below into it

const express = require('express'),

app = express(),

port = process.env.PORT || 3000; app.listen(port); console.log('book list RESTful API server started on: ' + port);

In your terminal, run npm start. This will start the server and you should see the following:

book list RESTful API server started on: 3000

Setting up the schema

First, let’s install mongoose —

npm install mongoose

Why Mongoose?

MongoDB is a NoSQL database that stores data in JSON format and is ready to deal with large volumes of data. It uses a JavaScript-based structure, and it is very easy to persist and read it’s data from a Node.js application.

After installation, open the bookListModel.js file in your api/models folder and punch in the following code.

'use strict';

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const BookSchema = new Schema({

name: {

type: String,

required: 'Enter book name'

},

Created_date: {

type: Date,

default: Date.now

},

status: {

type: [{

type: String,

enum: ['pending', 'ongoing', 'completed']

}],

default: ['pending']

}

}); module.exports = mongoose.model('Books', BookSchema);

Sweet! We required the mongoose in our file and then we created a model of our data structure.

As you can see, the table will contain a name as a string, and the date it was created. It also contains a status which we have defined as pending — a default value for every book created.

Setting up the routes

Routing determines how an application responds to a client request for a specific endpoint. Each of our routes has different route handler functions, which are executed when the route is matched. Below we have defined two basic routes(‘/books’, and ‘/books/bookId’) with different methods.

‘/books’ has two methods GET and POST. While ‘/books/bookId’ has GET, PUT, and DELETE.

As you can see, we required the controller so each of the route methods can call its respective handler function.

Let's jump back to our code and get this started! Open the bookListRoutes.js file in the routes folder and copy/paste the code snippet below

'use strict';

module.exports = (app) => {

const bookList = require('../controllers/bookListController'); // bookList Routes

app.route('/books')

.get(bookList.list_all_books)

.post(bookList.create_a_book);

app.route('/books/:bookId')

.get(bookList.read_a_book)

.put(bookList.update_a_book)

.delete(bookList.delete_a_book);

};

Setting up the controller

In the bookListController.js controller, we will be writing five different functions: list_all_books, create_a_book, read_a_book, update_a_book, and delete_a_book. Each of these functions uses different mongoose methods such as find, findById, findOneAndUpdate, save, and remove.

'use strict';

const mongoose = require('mongoose'),

Book = mongoose.model('Books'); exports.list_all_books = (req, res) => {

Book.find({}, (err, book) => {

if (err)

res.send(err);

res.json(book);

});

};

exports.create_a_book = (req, res) => {

let new_book = new Book(req.body);

new_book.save((err, book) => {

if (err)

res.send(err);

res.json(book);

});

};

exports.read_a_book = (req, res) => {

Book.findById(req.params.bookId, (err, book) => {

if (err)

res.send(err);

res.json(book);

});

};

exports.update_a_book = (req, res) => {

Book.findOneAndUpdate({_id: req.params.bookId}, req.body, {new: true}, (err, task) => {

if (err)

res.send(err);

res.json(book);

});

};

exports.delete_a_book = (req, res) => {

Book.remove({

_id: req.params.bookId

}, (err, book) => {

if (err)

res.send(err);

res.json({ message: 'Book successfully deleted' });

});

};

Putting everything together

Homestretch! In this section, we will be connecting our controllers, database, created models, and the created routes.

We just have a couple of steps we need to knock out before we can put everything together!

Connect our database by adding a URL to the mongoose instance connection Load the created model — book Register our created routes to the server

const express = require('express')

app = express()

port = process.env.PORT || 3000

mongoose = require('mongoose')

const uri = 'mongodb://localhost/Bookdb';

Book = require('./api/models/bookListModel') //created model loading here // mongoose instance connection url connection mongoose.connect(uri, {

useNewUrlParser: true,

useCreateIndex: true,

useUnifiedTopology: true

}).then(res=>{

console.log("DB Connected!")

}).catch(err => {

console.log(Error, err.message);

}) app.use(express.urlencoded({ extended: true }))

app.use(express.json()); const routes = require('./api/routes/bookListRoutes'); //importing route routes(app); //register the route app.get('*', (req, res)=>{

res.status(404).send({url: req.originalUrl + ' not found'})

}) app.listen(port);

console.log('book list RESTful API server started on: ' + port);

Open your terminal and run mongod

This will start your MongoDB server. The Node server can connect to the MongoDB instance. Once your MongoDB server is running, restart your Node server by running: rs on your Nodemon running terminal.

Testing via Postman

Now that everything is now connected, let’s test each of the routes and the respective methods.

Open Postman and type:

http://localhost:3000/books in the enter request URL section and hit enter.

You should get back an empty array since there is nothing in the database yet.

On the same address, change the method to POST, click body, and select “x-www-form-urlencoded”. Then, enter name as the key and a book name of your choice as a value, and hit send.

Voila! You just made a quick and simple RESTful API with Node.js and MongoDB! This was a learning experience for me as I’ve never used Node or MongoDB before. Hopefully, this can lead us all down a path of continued learning. If you have any questions, feel free to reach me on LinkedIn. I’d love to hear if this helped anyone. Happy Coding!