{"id":19821,"date":"2015-05-26T09:48:18","date_gmt":"2015-05-26T04:18:18","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=19821"},"modified":"2020-11-24T12:04:11","modified_gmt":"2020-11-24T06:34:11","slug":"build-restful-api-using-node-and-hapi","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/build-restful-api-using-node-and-hapi\/","title":{"rendered":"Build RESTful API Using Node and Hapi"},"content":{"rendered":"<p>With the increasing popularity of <a title=\"Node.js Development\" href=\"http:\/\/www.tothenew.com\/mean-node-js-development-consulting\">Hapi in the Node community<\/a>, it is a good option to build API&#8217;s using this framework. Let&#8217;s understand the Hapi framework and how easily we can define routes to build Hapi RESTful API for production ready environment. We will also be using some of the Hapi plugin&#8217;s for ease of API&#8217;s validation and to test routes.<\/p>\n<p>Let&#8217;s look at the API we want to build and what it can do.<\/p>\n<p><strong>Our Application<\/strong><\/p>\n<p>We are going to build an API that will:<\/p>\n<ul>\n<li>Handle CRUD for an item ( we&#8217;re are going to use `user` )<\/li>\n<li>Have a standard URL ( &#8220;http:\/\/demo.com\/api\/user&#8221; and &#8220;http:\/\/demo.com\/api\/user\/:id&#8221; )<\/li>\n<li>Use the proper HTTP verbs to make it RESTful ( GET, POST, PUT, and DELETE )<\/li>\n<li>Return JSON data<\/li>\n<li>Log all request to the console<\/li>\n<\/ul>\n<p>All of this is pretty standard for RESTful API&#8217;s. Feel free to switch out &#8216;user&#8217; with\u00a0anything that you want to build for the application ( cart, ship, company, etc ).<\/p>\n<p>Make sure you have Node installed and let&#8217;s get to it!<\/p>\n<p style=\"text-align: center\"><span style=\"color: #0000ff\"><a style=\"color: #0000ff\" title=\"GitHub Source Code Link\" href=\"https:\/\/github.com\/kashishgupta1990\/RESTfulHapiApi\" target=\"_blank\">GitHub Source Code Link<\/a><\/span><\/p>\n<p><strong>Getting Started<\/strong><\/p>\n<p>Let\u2019s look at all the files we will need to create our API. We will need to\u00a0define our Node\u00a0packages, start our server using Hapi, define our model, register our plugin&#8217;s,\u00a0declare our routes using Hapi, and last but not least, document and dry run API using Hapi Swagger.<\/p>\n<p>Here is our file structure. When moving to a production or larger application, you\u2019ll want to separate things out into a good structure (like having your routes in their own file).<\/p>\n<pre class=\" language-javascript\"><code class=\" language-javascript\">    <span class=\"token operator\">-<\/span> models<span class=\"token operator\">\/<\/span>\r\n    <span class=\"token operator\">--<\/span><span class=\"token operator\">--<\/span> user<span class=\"token punctuation\">.<\/span>js        <span class=\"token comment\">\/\/ our user model<\/span>\r\n    <span class=\"token operator\">-<\/span> node_modules<span class=\"token operator\">\/<\/span>     <span class=\"token comment\">\/\/ created by npm. holds our dependencies\/packages<\/span>\r\n    <span class=\"token operator\">-<\/span> <span class=\"token keyword keyword-package\">package<\/span><span class=\"token punctuation\">.<\/span>json      <span class=\"token comment\">\/\/ define all our node app and dependencies<\/span>\r\n    <span class=\"token operator\">-<\/span> app<span class=\"token punctuation\">.<\/span>js            <span class=\"token comment\">\/\/ configure our application and create routes\r\n<\/span><\/code><\/pre>\n<p><strong>Defining our Node Packages <\/strong>(<em>package.json<\/em>)<\/p>\n<p>Like our other Node projects, we will define the modules\u00a0we need in\u00a0<code>package.json<\/code>. Go ahead and create that file with these dependencies.<\/p>\n<pre class=\" language-javascript\"><code class=\" language-javascript\"><span class=\"token comment\">\/\/ package.json<\/span>\r\n<span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token string\">\"name\"<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"RESTful-HAPI\"<\/span><span class=\"token punctuation\">,\r\n<\/span>    \"version\": \"0.0.1\",\r\n    <span class=\"token string\">\"main\"<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"app.js\"<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token string\">\"dependencies\"<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token string\">\"good-console\"<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"^5.0.0\"<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">\"hapi\"<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"^8.5.1\"<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">\"hapi-swagger\"<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">\"0.7.3\",\r\n<\/span>        \"joi\": \"^6.4.2\",\r\n        \"mongoose\": \"^4.0.3\"\r\n    <span class=\"token punctuation\">}<\/span>\r\n<span class=\"token punctuation\">}<\/span><\/code><\/pre>\n<p><em><span class=\"text-info\">What do these packages do?<\/span><\/em>\u00a0<span style=\"font-family: Consolas, Monaco, 'Lucida Console', monospace\"><span style=\"font-size: 12px\">hapi<\/span><\/span>\u00a0is the Node framework. <code>mongoose\u00a0<\/code>is the ORM we will use to <a title=\"Full-\u00adstack MEAN development \" href=\"http:\/\/www.tothenew.com\/mean-stack-web-development-consulting\">communicate with our MongoDB database<\/a>. <span style=\"font-family: Consolas, Monaco, 'Lucida Console', monospace\"><span style=\"font-size: 12px\">good-console<\/span><\/span>\u00a0will let us see the URL&#8217;s logged on server console.\u00a0<span style=\"font-size: 12px\">joi<\/span>\u00a0is hapi plugin use to validate request params and payload data. <span style=\"font-size: 12px\">hapi-swagger<\/span>\u00a0is Hapi plugin use to test API&#8217;s URL with request and valid response.<\/p>\n<p><strong>Installing our Node Packages<\/strong><\/p>\n<p>This might be the easiest step. Go into the command line in the root of your application and type:<\/p>\n<pre class=\" language-javascript\"><code class=\" language-javascript\">$ npm install<\/code><\/pre>\n<p>npm will now pull in all the packages defined into a <code>node_modules<\/code> folder in our project.<\/p>\n<p><code>npm<\/code> is Node\u2019s package manager that will bring in all the packages we defined in <code>package.json<\/code>. Now that we have our packages, let\u2019s go ahead and use them to set up our API.<\/p>\n<p>We\u2019ll be looking to our <code>app.js<\/code> file to setup our app since that\u2019s the\u00a0<code>main<\/code> file we declared in <code>package.json<\/code>.<\/p>\n<p><strong>Setting up our server <\/strong>( <em>app.js<\/em> )<\/p>\n<p>Node will look here when starting the application so that it will know how we want to configure our application and API.<\/p>\n<p>We will start with the user essentials necessary to start up our application.<\/p>\n<pre>\/\/ ================ Base Setup ========================\r\n\/\/ Include Hapi package\r\nvar Hapi = require('hapi');\r\n\r\n\/\/ Create Server Object\r\nvar server = new Hapi.Server();\r\n\r\n\/\/ Define PORT number\r\nserver.connection({port: 7002});\r\n\r\n\/\/ =============== Routes for our API =======================\r\n\/\/ Define GET route\r\nserver.route({\r\n    method: 'GET',      \/\/ Methods Type\r\n    path: '\/api\/user',  \/\/ Url\r\n    handler: function (request, reply) { \/\/Action\r\n\r\n        \/\/ Response JSON object\r\n        reply({\r\n            statusCode: 200,\r\n            message: 'Getting All User Data',\r\n            data: [\r\n                {\r\n                    name:'Kashish',\r\n                    age:24\r\n                },\r\n                {\r\n                    name:'Shubham',\r\n                    age:21\r\n                },\r\n                {\r\n                    name:'Jasmine',\r\n                    age:24\r\n                }\r\n            ]\r\n        });\r\n    }\r\n});\r\n\r\n\/\/ =============== Start our Server =======================\r\n\/\/ Lets start the server\r\nserver.start(function () {\r\n    console.log('Server running at:', server.info.uri);\r\n});<\/pre>\n<p><strong class=\"text-info\">Base Setup<\/strong> In our base setup, we pull in all the packages we pulled in using npm. We\u2019ll grab hapi, define our server object, call the connection method and pass the configuration where we set our port ( port: 7002).<\/p>\n<p><strong class=\"text-info\">Routes for Our API<\/strong> This section will hold all of our routes. The structure for using the Hapi\u00a0Router. Let us call the route method and pass the route configuration object which holds the `method type`( GET ), `path`( \/api\/user ), `handler`to do all the action work.<\/p>\n<p><strong class=\"text-info\">Start our Server<\/strong> We\u2019ll have our hapi\u00a0app listen to the port we defined earlier (that is 7002). Then our application will be live and we will be able to test it.<\/p>\n<p>We can test our application using POSTMAN plugin of browser. But what if application itself gives you the ability to test your routes with well documented way using <strong>Hapi Swagger plugin<\/strong>. Let&#8217;s see how easy it is to register any hapi plugin.<\/p>\n<p><strong>Register your plugin<\/strong><\/p>\n<p>`register` method is used to register a plugin. Hapi register method only accepts a\u00a0configurable object.<\/p>\n<pre>\/\/ ================ Base Setup ========================\r\n\/\/ Include Hapi package\r\nvar Hapi = require('hapi');\r\n\r\n\/\/ Create Server Object\r\nvar server = new Hapi.Server();\r\n\r\n\/\/ Define PORT number\r\nserver.connection({port: 7002});\r\n\r\n\/\/ Register Swagger Plugin ( Use for documentation and testing purpose )\r\nserver.register({\r\n    register: require('hapi-swagger'),\r\n    options: {\r\n        apiVersion: \"0.0.1\"\r\n    }\r\n}, function (err) {\r\n    if (err) {\r\n        server.log(['error'], 'hapi-swagger load error: ' + err)\r\n    } else {\r\n        server.log(['start'], 'hapi-swagger interface loaded')\r\n    }\r\n});\r\n\r\n\/\/ =============== Routes for our API =======================\r\n\/\/ Define GET route\r\nserver.route({\r\n    method: 'GET',      \/\/ Methods Type\r\n    path: '\/api\/user',  \/\/ Url\r\n    config: {\r\n        \/\/ Include this API in swagger documentation\r\n        tags: ['api'],\r\n        description: 'Get All User data',\r\n        notes: 'Get All User data'\r\n    },\r\n    handler: function (request, reply) { \/\/Action\r\n\r\n        \/\/ Response JSON object\r\n        reply({\r\n            statusCode: 200,\r\n            message: 'Getting All User Data',\r\n            data: [\r\n                {\r\n                    name:'Kashish',\r\n                    age:24\r\n                },\r\n                {\r\n                    name:'Shubham',\r\n                    age:21\r\n                }\r\n            ]\r\n        });\r\n    }\r\n});\r\n\r\n\/\/ =============== Start our Server =======================\r\n\/\/ Lets start the server\r\nserver.start(function () {\r\n    console.log('Server running at:', server.info.uri);\r\n});<\/pre>\n<p><strong>register method<\/strong> <em>first argument<\/em> accept { register` and `options` } fields are mandatory fields which further accept the configuration and <em>second argument accept <\/em>callback method which has one argument ( error ) to confirm that the plugin is successfully loaded.<\/p>\n<p><strong>Enable Swagger Testing \/ Documentation For Routes<\/strong><\/p>\n<p>You just have to add `<strong>tags:[&#8216;api&#8217;]<\/strong>` property into `<strong>config<\/strong>` object and other two (description, notes) are optional fields.<\/p>\n<p><strong>Starting Our Server and Testing<\/strong><\/p>\n<p>Let\u2019s make sure that everything is working up to this point. We will start our Node app and then send a request to the one route we defined to make sure we get a response.<\/p>\n<p>Let\u2019s start our server. From the command line, type:<\/p>\n<pre class=\" language-javascript\"><code class=\" language-javascript\">$ node app<span class=\"token punctuation\">.<\/span>js<\/code><\/pre>\n<p>You should see your Node app start up and Hapi\u00a0will create a server.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/RuningServer1.png\"><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-20020\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/RuningServer1.png\" alt=\"Runing Server\" width=\"479\" height=\"156\" \/><\/a><\/p>\n<p>Now that we know our application is up and running, let\u2019s test it. You can checkout on <em>http:\/\/localhost:7002\/api\/user<\/em><\/p>\n<p><strong>Testing our API Using Swagger<\/strong><\/p>\n<p>Swagger\u00a0will help us test our API. It will basically send HTTP requests to a URL of our choice. We can even pass in parameters (which we will soon) and authentication (which we won\u2019t need for this tutorial).<\/p>\n<p>Open up Swagger ( http:\/\/localhost:7002\/documentation ) and let\u2019s walk through how to use it.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/swagger1.png\"><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-20021\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/swagger1.png\" alt=\"swagger\" width=\"602\" height=\"229\" \/><\/a><\/p>\n<p>All you have to do is click on <strong>api\/user <\/strong>and then click the button &#8216;<strong>Try It out!&#8217;.<\/strong><\/p>\n<p>Now we know we can serve information to requests. Let\u2019s wire up our database so we can start performing CRUD operations on some user.<\/p>\n<p><strong>Database and User Model<\/strong><\/p>\n<p>We\u2019ll keep this short and crisp\u00a0so that we can get to the fun part of building the API routes. All we need to do is create a MongoDB database and have our application connect to it. We will also need to create a user\u00a0mongoose model so we can use mongoose to interact with our database.<\/p>\n<p><strong>Creating our database and Connecting<\/strong><\/p>\n<p>We will be using a local database. You can definitely use some other providers like Modulus and use it online or use the awesome Mongolab. All you really need is a URI like below so that your application can connect.<\/p>\n<p>Once you have your database created and have the URI to connect to, add it to the application. In app<code>.js<\/code> in the Base Setup section, let\u2019s add below lines. Ensure that you have mongoDB installed locally if you use local database.<\/p>\n<pre class=\"line-numbers language-javascript\"><code class=\" language-javascript\"><span class=\"token keyword keyword-var\">var<\/span> mongoose   <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'mongoose'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\nmongoose<span class=\"token punctuation\">.<\/span><span class=\"token function\">connect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'<a class=\"token url-link\" href=\"node\">mongodb:\/\/<\/a>localhost\/restdemo'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token comment\">\/\/ connect to local database<\/span><\/code><\/pre>\n<p>That will grab the mongoose package and connect to our local\u00a0database. Now that we are connected to our database, let\u2019s create a mongoose model to handle our users.<\/p>\n<p><strong>User Model <\/strong>(<em> models\/user.js<\/em> )<\/p>\n<p>Since the model won\u2019t be the focus of this tutorial, we\u2019ll just create a model and provide our users with a name and age field. That\u2019s it. Let\u2019s create that file and define the model.<\/p>\n<pre>var mongoose = require('mongoose');\r\nvar Schema = mongoose.Schema;\r\n\r\nvar UserSchema = new Schema({\r\n    name: String,\r\n    age: Number\r\n});\r\n\r\nmodule.exports = mongoose.model('User', UserSchema, 'User');<\/pre>\n<p>With that file created, let\u2019s pull it into our app<code>.js<\/code> so that we can use it within our application. We\u2019ll add one more line to that file.<\/p>\n<pre>\/\/ ================ Base Setup ========================\r\n\/\/ Include Hapi package\r\nvar Hapi = require('hapi');\r\n\r\n\/\/ Create Server Object\r\nvar server = new Hapi.Server();\r\n\r\n\/\/ Include Mongoose ORM to connect with database\r\nvar mongoose = require('mongoose');\r\n\r\n\/\/ Making connection with `restdemo` database in your local machine\r\nmongoose.connect('mongodb:\/\/localhost\/restdemo');\r\n\r\n\/\/ Importing `user` model from `models\/user.js` file\r\nvar UserModel = require('.\/models\/user');\r\n\r\n\/\/ Define PORT number\r\nserver.connection({port: 7002});\r\n\r\n\/\/ Register Swagger Plugin ( Use for documentation and testing purpose )\r\nserver.register({\r\n    register: require('hapi-swagger'),\r\n    options: {\r\n        apiVersion: \"0.0.1\"\r\n    }\r\n}, function (err) {\r\n    if (err) {\r\n        server.log(['error'], 'hapi-swagger load error: ' + err)\r\n    } else {\r\n        server.log(['start'], 'hapi-swagger interface loaded')\r\n    }\r\n});\r\n\r\n\/\/ =============== Routes for our API =======================\r\n\/\/ Define GET route\r\nserver.route({\r\n    method: 'GET',      \/\/ Methods Type\r\n    path: '\/api\/user',  \/\/ Url\r\n    config: {\r\n        \/\/ Include this API in swagger documentation\r\n        tags: ['api'],\r\n        description: 'Get All User data',\r\n        notes: 'Get All User data'\r\n    },\r\n    handler: function (request, reply) { \/\/Action\r\n\r\n        \/\/ Response JSON object\r\n        reply({\r\n            statusCode: 200,\r\n            message: 'Getting All User Data',\r\n            data: [\r\n                {\r\n                    name:'Kashish',\r\n                    age:24\r\n                },\r\n                {\r\n                    name:'Shubham',\r\n                    age:21\r\n                }\r\n            ]\r\n        });\r\n    }\r\n});\r\n\r\n\/\/ =============== Start our Server =======================\r\n\/\/ Lets start the server\r\nserver.start(function () {\r\n    console.log('Server running at:', server.info.uri);\r\n});<\/pre>\n<p>Now our entire application is ready and wired up so we can start building out our routes. These routes will define our API and the main reason why this tutorial exists.<\/p>\n<p><strong>Hapi Routes<\/strong><\/p>\n<p>We will use Hapi route method\u00a0to handle all of our routes. Here is an overview of the routes we will require, what they will do, and the HTTP Verb used to access it.<\/p>\n<table class=\"table table-striped table-bordered\" style=\"height: 222px\" width=\"669\">\n<thead>\n<tr>\n<td><strong>Route<\/strong><\/td>\n<td><strong>HTTP Verb<\/strong><\/td>\n<td><strong>Description<\/strong><\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\/api\/user<\/td>\n<td><code>GET<\/code><\/td>\n<td>Get all the users.<\/td>\n<\/tr>\n<tr>\n<td>\/api\/user<\/td>\n<td><code>POST<\/code><\/td>\n<td>Create a new user.<\/td>\n<\/tr>\n<tr>\n<td>\/api\/user\/{id}<\/td>\n<td><code>GET<\/code><\/td>\n<td>Get a single user.<\/td>\n<\/tr>\n<tr>\n<td>\/api\/user\/{id}<\/td>\n<td><code>PUT<\/code><\/td>\n<td>Update a user\u00a0with new info.<\/td>\n<\/tr>\n<tr>\n<td>\/api\/user\/{id}<\/td>\n<td><code>DELETE<\/code><\/td>\n<td>Delete a user.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This will cover the basic routes needed for an API. This also maintains a good format where it stores the actions needed to execute (GET, POST, PUT, and DELETE) as HTTP verbs.<\/p>\n<p><strong>Creating the Basic Routes<\/strong><\/p>\n<p>We will now create the routes to handle <strong>getting all the users<\/strong>\u00a0and <strong>creating a user<\/strong>. This will both be handled using the <code>\/api\/user<\/code>\u00a0route. We\u2019ll look at creating a user\u00a0first so that we have users\u00a0to work with.<\/p>\n<p><strong>Create a User\u00a0<\/strong>( <em>POST \/api\/user<\/em>\u00a0)<\/p>\n<p>We will add the new route to handle POST and then test it using Hapi\u00a0Swagger.<\/p>\n<pre>server.route({\r\n    method: 'POST',\r\n    path: '\/api\/user',\r\n    config: {\r\n        \/\/ \"tags\" enable swagger to document API\r\n        tags: ['api'],\r\n        description: 'Save user data',\r\n        notes: 'Save user data',\r\n        \/\/ We use Joi plugin to validate request\r\n        validate: {\r\n            payload: {\r\n                \/\/ Both name and age are required fields\r\n                name: Joi.string().required(),\r\n                age: Joi.number().required()\r\n            }\r\n        }\r\n    },\r\n    handler: function (request, reply) {\r\n\r\n        \/\/ Create mongodb user object to save it into database\r\n        var user = new UserModel(request.payload);\r\n\r\n        \/\/ Call save methods to save data into database\r\n        \/\/ and pass callback methods to handle error\r\n        user.save(function (error) {\r\n            if (error) {\r\n                reply({\r\n                    statusCode: 503,\r\n                    message: error\r\n                });\r\n            } else {\r\n                reply({\r\n                    statusCode: 201,\r\n                    message: 'User Saved Successfully'\r\n                });\r\n            }\r\n        });\r\n    }\r\n});<\/pre>\n<p>Now we have created the <code>POST<\/code> route for our application. We will use Hapi\u00a0\u00a0<code>server.route({})<\/code> to handle multiple routes for the same URI. We are able to handle all the requests that end in <code>\/user<\/code>.<\/p>\n<p>Let\u2019s look at Swagger\u00a0now to create our user.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/rsz_1post_before_send.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20065\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/rsz_1post_before_send.png\" alt=\"rsz_1post_before_send\" width=\"1029\" height=\"457\" \/><\/a><\/p>\n<p>Notice that we are preparing our user JSON to send as POST request and &#8220;name&#8221; and &#8220;age&#8221; are required field here. Let&#8217;s see the response of the above request we made.<\/p>\n<p>We can easily see the response we have just got with statusCode:201 and message:&#8221;User Saved Successfully&#8221;<\/p>\n<p><strong>Get All the Users\u00a0<\/strong>( <em>GET \/api\/user<\/em> )<\/p>\n<p>Now we have a\u00a0user in our database, so why not to get all the users from the database by defining GET route in our application to fetch all users.<\/p>\n<pre>\/\/ Fetching all users data\r\nserver.route({\r\n    method: 'GET',\r\n    path: '\/api\/user',\r\n    config: {\r\n        \/\/ Include this API in swagger documentation\r\n        tags: ['api'],\r\n        description: 'Get All User data',\r\n        notes: 'Get All User data'\r\n    },\r\n    handler: function (request, reply) {\r\n        \/\/Fetch all data from mongodb User Collection\r\n        UserModel.find({}, function (error, data) {\r\n            if (error) {\r\n                reply({\r\n                    statusCode: 503,\r\n                    message: 'Failed to get data',\r\n                    data: error\r\n                });\r\n            } else {\r\n                reply({\r\n                    statusCode: 200,\r\n                    message: 'User Data Successfully Fetched',\r\n                    data: data\r\n                });\r\n            }\r\n        });\r\n    }\r\n});<\/pre>\n<p>Now we have created the GET route in our application to fetch all record. Let&#8217;s check this on Swagger.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/rsz_get-all-user-request.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone  wp-image-20066\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/rsz_get-all-user-request.png\" alt=\"rsz_get-all-user-request\" width=\"428\" height=\"308\" \/><\/a><\/p>\n<p>We can see that all the user data get fetched with database &#8220;_id&#8221; keys. Why not get single user data by just passing unique key as shown above with &#8220;_id&#8221;?<\/p>\n<p><strong>Creating Route for A Single Item<\/strong><\/p>\n<p>We\u2019ve handled the group for routes ending in <code>\/user<\/code>. Let\u2019s now handle the routes for when we pass in a parameter like a user&#8217;s\u00a0id.<\/p>\n<p>The things we\u2019ll want to do for this route, which will end in<code>\/user\/{id}<\/code> will be:<\/p>\n<ul>\n<li>Get a single user.<\/li>\n<li>Update a user&#8217;s\u00a0info.<\/li>\n<li>Delete a user.<\/li>\n<\/ul>\n<p><strong>Getting a single User\u00a0<\/strong>( <em>GET<\/em>\u00a0<em>\/api\/user\/{id}<\/em> )<\/p>\n<p>We\u2019ll add another server<code>.route({})<\/code> to handle all requests that have a {<code>id}<\/code>\u00a0attached to them.<\/p>\n<pre>server.route({\r\n    method: 'GET',\r\n    \/\/Getting data for particular user \"\/api\/user\/1212313123\"\r\n    path: '\/api\/user\/{id}',\r\n    config: {\r\n        tags: ['api'],\r\n        description: 'Get specific user data',\r\n        notes: 'Get specific user data',\r\n        validate: {\r\n            \/\/ Id is required field\r\n            params: {\r\n                id: Joi.string().required()\r\n            }\r\n        }\r\n    },\r\n    handler: function (request, reply) {\r\n\r\n        \/\/Finding user for particular userID\r\n        UserModel.find({_id: request.params.id}, function (error, data) {\r\n            if (error) {\r\n                reply({\r\n                    statusCode: 503,\r\n                    message: 'Failed to get data',\r\n                    data: error\r\n                });\r\n            } else {\r\n                if (data.length === 0) {\r\n                    reply({\r\n                        statusCode: 200,\r\n                        message: 'User Not Found',\r\n                        data: data\r\n                    });\r\n                } else {\r\n                    reply({\r\n                        statusCode: 200,\r\n                        message: 'User Data Successfully Fetched',\r\n                        data: data\r\n                    });\r\n                }\r\n            }\r\n        });\r\n    }\r\n});<\/pre>\n<p>From our call to get all the user&#8217;s, we can see the long id of one of our users. Let\u2019s grab that id and test getting that single user in Swagger. Let see how\u00a0a request looks in Swagger.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/GET-Single-User-data-request1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone  wp-image-20022\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/GET-Single-User-data-request1.png\" alt=\"GET-Single-User-data-request\" width=\"467\" height=\"245\" \/><\/a><\/p>\n<p>Now when we click on <strong>Try it out!<\/strong> button we get the response with single user data.<\/p>\n<p>We can grab one user from our API now! Let\u2019s look at updating that user\u2019s name. Let\u2019s say he forgot to mention his last name so we\u2019ll rename him from <strong>Shubham<\/strong> to <strong>Shubham Gupta<\/strong>.<\/p>\n<p><strong>Updating a user&#8217;s info\u00a0<\/strong>( <em>PUT \/api\/user<\/em>\u00a0)<\/p>\n<pre>server.route({\r\n    method: 'PUT',\r\n    path: '\/api\/user\/{id}',\r\n    config: {\r\n        \/\/ Swagger documentation fields tags, description, note\r\n        tags: ['api'],\r\n        description: 'Update specific user data',\r\n        notes: 'Update specific user data',\r\n\r\n        \/\/ Joi api validation\r\n        validate: {\r\n            params: {\r\n                \/\/`id` is required field and can only accept string data\r\n                id: Joi.string().required()\r\n            },\r\n            payload: {\r\n                name: Joi.string(),\r\n                age: Joi.number()\r\n            }\r\n        }\r\n    },\r\n    handler: function (request, reply) {\r\n\r\n        \/\/ `findOneAndUpdate` is a mongoose modal methods to update a particular record.\r\n        UserModel.findOneAndUpdate({_id: request.params.id}, request.payload, function (error, data) {\r\n            if (error) {\r\n                reply({\r\n                    statusCode: 503,\r\n                    message: 'Failed to get data',\r\n                    data: error\r\n                });\r\n            } else {\r\n                reply({\r\n                    statusCode: 200,\r\n                    message: 'User Updated Successfully',\r\n                    data: data\r\n                });\r\n            }\r\n        });\r\n\r\n    }\r\n});<\/pre>\n<p>Now let&#8217;s see how a request looks at Swagger UI.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/PUT-Update-User-Data-Request1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20024\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/PUT-Update-User-Data-Request1.png\" alt=\"PUT-Update-User-Data-Request\" width=\"1303\" height=\"640\" \/><\/a><\/p>\n<p>A response will return old data with status code as true, which means data has been updated successfully.<\/p>\n<p>We can also use the <code>GET \/api\/user<\/code>\u00a0call we used earlier to see that his name is changed.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/Showing-Updated-name1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20026\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/Showing-Updated-name1.png\" alt=\"Showing-Updated-name\" width=\"1027\" height=\"677\" \/><\/a><\/p>\n<p><strong>Deleting a User\u00a0<\/strong>( <em>DELETE \/api\/user<\/em> )<\/p>\n<p>When someone requests that a user\u00a0is deleted, all they have to do is send a DELETE to <code>\/api\/user\/{id}<\/code><\/p>\n<p>Let\u2019s add the code for deleting user.<\/p>\n<pre>server.route({\r\n    method: 'DELETE',\r\n    path: '\/api\/user\/{id}',\r\n    config: {\r\n        tags: ['api'],\r\n        description: 'Remove specific user data',\r\n        notes: 'Remove specific user data',\r\n        validate: {\r\n            params: {\r\n                id: Joi.string().required()\r\n            }\r\n        }\r\n    },\r\n    handler: function (request, reply) {\r\n\r\n        \/\/ `findOneAndRemove` is a mongoose methods to remove a particular record into database.\r\n        UserModel.findOneAndRemove({_id: request.params.id}, function (error) {\r\n            if (error) {\r\n                reply({\r\n                    statusCode: 503,\r\n                    message: 'Error in removing User',\r\n                    data: error\r\n                });\r\n            } else {\r\n                reply({\r\n                    statusCode: 200,\r\n                    message: 'User Deleted Successfully'\r\n                });\r\n            }\r\n        });\r\n\r\n    }\r\n});<\/pre>\n<p>Now when we send a request to our API using <code>DELETE<\/code> with the <code>_id<\/code>, we\u2019ll delete our user from existence. Let delete <strong>Shubham Gupta<\/strong> user from collection.<\/p>\n<p><a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/DELETE-User-Removed1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-20027\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/05\/DELETE-User-Removed1.png\" alt=\"DELETE-User-Removed\" width=\"1302\" height=\"909\" \/><\/a><\/p>\n<p>When we try to get <strong>Shubham Gupta<\/strong>\u00a0with same <em>_id<\/em>\u00a0from user collection, there will be nothing left and showing User not found.<\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>We now have the means to handle CRUD on a specific resource (our beloved users) through our own API. Using the techniques above should be a good foundation to move into building larger and more robust APIs.<\/p>\n<p>This has been a quick look at creating a Node API using HapiJs. There are many more things you can do with your own APIs. You can add authentication, create better error messages, add different sections so you\u2019re not just working with users.<\/p>\n<p>Hope this help. \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With the increasing popularity of Hapi in the Node community, it is a good option to build API&#8217;s using this framework. Let&#8217;s understand the Hapi framework and how easily we can define routes to build Hapi RESTful API for production ready environment. We will also be using some of the Hapi plugin&#8217;s for ease of [&hellip;]<\/p>\n","protected":false},"author":135,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":10},"categories":[1185],"tags":[2177,1819,2176],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/19821"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/135"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=19821"}],"version-history":[{"count":1,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/19821\/revisions"}],"predecessor-version":[{"id":53553,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/19821\/revisions\/53553"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=19821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=19821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=19821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}