Build a RESTful API using hapijs and MongoDB
Build a RESTful API using hapijs and MongoDB

This is the beginning of a new series about hapijs (from now on only hapijs). If you never heard of hapi before: it is a Node.js web framework for websites and webservices like Express but with some differences. When familiar with Express you should have no trouble following this tutorial…

Build a RESTful API using hapijs and MongoDB

Our Application

We are going to build a RESTful API that:

  • handles basic CRUD for an item (books in this case)
  • uses MongoDB to store and retrieve those books
  • validates the input and returns meaningful errors
  • works with JSON data
  • uses proper HTTP verbs (GET, POST, PATCH, DELETE)

So far this is pretty standard except maybe the validation part. This is fairly easy to build with hapi (as are many other things as you will see in the next tutorials).

Build a RESTful API using hapijs and MongoDB

Getting started

Make sure you have the latest version of Node installed on your machine (currently v7.7.1) as we use some of the new ES6 features.

Also you should have a MongoDB server up and running on your localhost. Make sure it listens to the default port: localhost:27017

Everything setup? Let’s continue…

Start fast

If you want to skip the step by step copy and paste, just clone the Github Repository and follow the explanations. Otherwise just skip this section.

Step 1: Setup project

This is the file structure of our application. It is very simple, but we already move out the routes into an own file.

Node dependencies

Create a new file named package.json with this content:

So what are all these packages for? hapijs should be clear. boom is used for http friendly errors. joi is used for the input validation. Both packages are from the hapi ecosystem. To access our db we use mongojs and node-uuid to generate the ids for our objects.

Now it is time to install our dependencies. Fire up your command line, navigate into the root directory of your app and type:

Step 2: Create a basic server

Our next step will be to create a basic server so we can see everything is up and running as expected.

Create our server.js file and fill in this content:

This code is very simple. First a server with a new connection on port 3000 is created. Then a route is added for handling GET requests on path /books which returns a simple text. Finally our server is started.

Starting and testing our server

Now let’s make sure that everything is working up to this point. We will start our app and then send a request to the one route we defined to make sure we get a response.

Start the server with this command:

Open your browser and navigate to http://localhost:3000/books. You should see our text…

Screenshot of browser

Step 3: Connect to local MongoDB

We use the mongojs library to connect to our local MongoDB server. This is very simple and we only need 2 additional lines of code. This is the beginning of our server.js file:

We first require the mongojs library. Then we store our db connection in so we can access it from everywhere we have access to our server.

Step 4: Add routes

Time to remove our test route and create the book resource. Create a new file routes/books.js with the following content:

This defines a new hapi plugin called routes-books which encapsulates our routes definitions and handlers. Plugins are a central concept of hapi and allow to build modular applications.

We need to register this newly created plugin in our server.js. This is the complete file how it should look like by now:

List all books: GET /books

The first route we implement is to list all the books currently stored in MongoDB. Add this code to our plugin in routes/books.js:

The implementation of the handler is fairly easy. We just call the find method of the books collection to return all documents and use reply to send them to the client. If something goes wrong we use Boom to return a 422 error.

List a single book: GET /books/:id

The next route we implement is to get one single book. Add this code to our plugin in routes/books.js:

In the handler we use the findOne method of the books collection. Note we get the id from the path via If no document is found we return a 404 error.

Create a new book: POST /books

In this route we implement a way to create new books. Add this code to our plugin in routes/books.js:

In this handler we obtain the json book object submitted by the client via request.payload. The we generate a unique id for and save it in our database with the save method of the books collection.


Here we made use of the input validation provided by hapi and Joi for the first time.

We validate the payload to have at least a title, an author and optionally an isbn. Also we define the data types and some restrictions on length.

If there are any violations hapi automatically sends back an appropriate and readable error message with status code 400. Our handler function gets never called in this case. So if our handler function is executed we can be sure of valid data – very cool.

Update a single book: PATCH /books/:id

In this route we implement a way to update an existing book. We use the PATCHmethod here and allow the update of individual fields or the whole document. Add this code to our plugin in routes/books.js:

This handler should not contain any surprises. We use the update method of the books collection to set all attributes that are provided by the client in request.payload.

In the validation part we say which attributes are valid and how they should look like. Also we say that at least one attribute must be set – so an empty object would be invalid.

Delete a single book: DELETE /books/:id

Build a RESTful API using hapijs and MongoDB

Finally we implement a route that allows the deletion of a single book. Add this code to our plugin in routes/books.js:

After all the other handlers this one should be pretty self explanatory.

Step 5: Testing our work

Now that we have finished coding we should test our work. You can use curlfor this or a tool like Postman.

How to use each of those tools is not part of this tutorial. I assume you are already familiar with one of these or something similar.


You can download the complete code of this tutorial on Github.

☞  Learn Nodejs by building 12 projects

☞ The Complete Node.js Developer Course (2nd Edition)

☞ NodeJS in Action

☞ Introduction to Node.js for Beginners

☞  Node.js – From Zero to Web App


  1. You’ve got CSS/styling in all the cut/paste sections eg this in your package.json
    name“: “hapi-rest-mongo”,


Please enter your comment!
Please enter your name here