Creating a REST API is a common task in web development. I really like the ecosystem of Hapi , so today I want to show you how to use the Plugins Dogwater and Bedwetter to create a RESTful API. Dogwater integrates the Waterline ORM , which is also used by Sails.js . Bedwetter uses our Waterline models to automatically create RESTful handlers for your API routes.

pizza REST API. You can find the source code of this example in our In this post we will create a. You can find the source code of this example in our hapi-rest-starter repository on github. If you have any questions please feel free to write a comment or contact me on twitter

Getting started

Before we can start, we need to install some dependencies:

$ npm install --save hapi dogwater bedwetter blipp sails-disk shortid

Or just clone the repo:

$ git clone [email protected] :wbkd/hapi-rest-starter-simple.git $ cd hapi-rest-starter-simple $ npm install $ npm start

After installing the dependencies we can write our basic Hapi setup.

index.js

var Hapi = require ( 'hapi' ) ; var server = new Hapi . Server ( ) ; server . connection ( { port : 1337 , host : 'localhost' } ) ; server . start ( function ( ) { console . log ( 'Server up and running at:' , server . info . uri ) ; } ) ;

We just created a simple Hapi server that runs on port 1337.

The Database Model

As I said, we want to create a pizza API, so we need to create a Waterline model . In this example it ’ s a pizza model that has an id, a name and ingredients. The model will be used by Dogwater/Waterline to create the database API. I prefer shortIDs so we are using shortid for the id attribute. You could also skip the id attribute and Waterline will automatically generate unique IDs (it increments an integer value beginning from zero).

./models/pizza.js

var shortid = require ( 'shortid' ) ; module . exports = { identity : 'pizza' , connection : 'pizzaDB' , attributes : { id : { type : 'string' , primaryKey : true , unique : true , defaultsTo : function ( ) { return shortid . generate ( ) ; } , } , name : { type : 'string' , required : true , } , ingredients : { type : 'array' , required : false , } , } , } ;

Dogwater Options

Dogwater is just a kind of adapter so that you can use Waterline in your Hapi application. To use the Waterline ORM we have to define three things.

Connections - Here we define the names of our connections and which adapters they should use Adapters - Here we define the name and type of the adapters we want to use Models - Our database models

For this example we are defining a connection called “ pizzaDB ” that uses the adapter “ pizzaDisk ” . The “ pizzaDisk ” adapter is using “ sails-disk ” to store our data. In order to use MongoDB for example, we just need to install “ sails-mongo ” and use it as our adapter \o/.

var dogwaterOptions = { connections : { pizzaDB : { adapter : 'pizzaDisk' , } , } , adapters : { pizzaDisk : 'sails-disk' , } , models : [ require ( './models/pizza.js' ) ] , } ;

Colors Of Europe Interactive Data Visualization (Zeit Online) Are you interested in a collaboration? We are specialized in creating custom data visualizations and web-based tools. Contact us Learn more Learn more

The REST Routes

Bedwetter does not create the routes for you but only the route handlers. This comes in handy when you not want to use an automatically generated handler for a route you can just write it yourself. Bedwetter matches the path and the method to create the appropriate handler of the route. For this example we are going to create the following routes.

./routes/pizza.js

var bedwetterOptions = { } ; module . exports = [ { path : '/pizza' , method : 'GET' , config : { handler : { bedwetter : bedwetterOptions , } , } , } , { path : '/pizza/{id}' , method : 'GET' , config : { handler : { bedwetter : bedwetterOptions , } , } , } , { path : '/pizza' , method : 'POST' , config : { handler : { bedwetter : bedwetterOptions , } , } , } , { path : '/pizza/{id}' , method : [ 'PATCH' , 'POST' ] , config : { handler : { bedwetter : bedwetterOptions , } , } , } , { path : '/pizza/{id}' , method : 'DELETE' , config : { handler : { bedwetter : bedwetterOptions , } , } , } , ] ;

As you can see we don ’ t have to configure Bedwetter. For this simple example we just pass an empty object as the options.

Loading Plugins

register method. As you can see we are also using the To use the Dogwater and Bedwetter plugins we are using themethod. As you can see we are also using the “ blipp ” plugin. It ’ s a tiny helper that prints out all existing routes at startup.

server . register ( [ { register : require ( 'blipp' ) , } , { register : require ( 'dogwater' ) , options : dogwaterOptions , } , { register : require ( 'bedwetter' ) , options : { } , } , ] , function ( err ) { if ( err ) { return console . log ( err ) ; } } ) ;

Putting it all together

http://localhost:1337 , configuring dogwater, loading the plugins, registering the routes and starting the server. You can find the source of this example in our Eventually our index.js file looks like this. We are creating a connection on, configuring dogwater, loading the plugins, registering the routes and starting the server. You can find the source of this example in our hapi-rest-example repository

index.js

var Hapi = require ( 'hapi' ) ; var server = new Hapi . Server ( ) ; server . connection ( { port : 1337 , host : 'localhost' } ) ; var dogwaterOptions = { connections : { pizzaDB : { adapter : 'pizzaDisk' , } , } , adapters : { pizzaDisk : 'sails-disk' , } , models : [ require ( './models/pizza' ) ] , } ; server . register ( [ { register : require ( 'blipp' ) , } , { register : require ( 'dogwater' ) , options : dogwaterOptions , } , { register : require ( 'bedwetter' ) , options : { } , } , ] , function ( err ) { if ( err ) { return console . log ( err ) ; } server . route ( require ( './routes/pizza' ) ) ; server . start ( function ( ) { console . log ( 'Pizza API up and running at:' , server . info . uri ) ; } ) ; } ) ;

If you run your server with node index.js you should see the output of blipp:

http://localhost:1337 GET /pizza POST /pizza GET /pizza/ { id } POST /pizza/ { id } PATCH /pizza/ { id } DELETE /pizza/ { id } Pizza API up and running at: http://localhost:1337

Now you can start using your REST API. You could use Postman or some curl commands to test it.

Examples:

Create a new pizza:

$ curl --data "name=Tuna&ingredients=tuna,cheese,tomatoes" https://localhost:1337/pizza

Get all pizzas: