Joi — awesome code validation for Node.js and Express

Joi — awesome code validation for Node.js and Express

Validation of data is an interesting topic, we tend to write code that looks really horrible in the sense that it contains a lot of checks.

Originally published by Chris Noring at dev.to

There are different situations when we need to perform these checks like validating a response from a backend endpoint or maybe verifying what goes into our REST API won’t break our code. We will focus on the latter, how to validate our API.

Consider the below code that we might need to write when we don't have a validation library:

if (!data.parameterX) { 
  throw new Exception('parameterX missing') 
} 
try { 
  let value = parseInt(data.parameterX); 
} catch (err) { 
  throw new Exception('parameterX should be number'); 
} 
if(!/[a-z]/.test(data.parameterY)) { 
  throw new Exception('parameterY should be lower caps text') 
}

I think you get the idea from the above cringe-worthy code. We tend to perform a lot of tests on our parameters to ensure they are the right and/or their values contains the allowed values.

As developers we tend to feel really bad about code like this, so we either start writing a lib for this or we turn to our old friend NPM and hope that some other developer have felt this pain and had too much time on their hands and made a lib that you could use.

There are many libs that will do this for you. I aim to describe a specific one called Joi.

https://github.com/hapijs/joi

Throughout this article we will take the following journey together:

  • Have a look at Joi’s features
  • See how we can use Joi in the backend in a Request pipeline
  • Improve even further by building a middleware for Express in Node.js
Introducing Joi

Installing Joi is quite easy. We just need to type:

npm install joi

After that, we are ready to use it. Let’s have a quick look at how we use it. The first thing we do is import it and then we set up some rules, like so:

const Joi = require('joi'); 
const schema = Joi.object().keys({ 
  name: Joi.string().alphanum().min(3).max(30).required(),
  birthyear: Joi.number().integer().min(1970).max(2013), 
}); 
const dataToValidate = { 
  name 'chris', 
  birthyear: 1971 
} 
const result = Joi.validate(dataToValidate, schema); 
// result.error == null means valid

What we are looking at above is us doing the following:

  • constructing a schema, our call to Joi.object(),
  • validating our data, our call to Joi.validate() with dataToValidateand schema as input parameters

Ok, now we understand the basic motions. What else can we do?

Well, Joi supports all sorts of primitives as well as Regex and can be nested to any depth. Let’s list some different constructs it supports:

  • string, this says it needs to be of type string, and we use it like so Joi.string()
  • number, Joi.number() and also supporting helper operations such as min() and max(), like so Joi.number().min(1).max(10)
  • required, we can say whether a property is required with the help of the method required, like so Joi.string().required()
  • any, this means it could be any type, usually, we tend to use it with the helper allow() that specifies what it can contain, like so, Joi.any().allow('a')
  • optional, this is strictly speaking not a type but has an interesting effect. If you specify for example prop : Joi.string().optional. If we don't provide prop then everybody's happy. However, if we do provide it and make it an integer the validation will fail
  • array, we can check whether the property is an array of say strings, then it would look like this Joi.array().items(Joi.string().valid('a', 'b')
  • regex, it supports pattern matching with RegEx as well like so Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/)

The whole API for Joi is enormous. I suggest to have a look and see if there is a helper function that can solve whatever case you have that I’m not showing above

Joi API

https://github.com/hapijs/joi/blob/v14.3.1/API.md
 Nested types

Ok, so we have only shown how to declare a schema so far that is one level deep. We did so by calling the following:

Joi.object().keys({ });

This stated that our data is an object. Then we added some properties to our object like so:

Joi.object().keys({ 
  name: Joi.string().alphanum().min(3).max(30).required(),
  birthyear: Joi.number().integer().min(1970).max(2013) 
});

Now, nested structures are really more of the same. Let’s create an entirely new schema, a schema for a blog post, looking like this:

const blogPostSchema = Joi.object().keys({ 
  title: Joi.string().alphanum().min(3).max(30).required(),
  description: Joi.string(), 
  comments: Joi.array().items(Joi.object.keys({ 
    description: Joi.string(), 
    author: Joi.string().required(), 
    grade: Joi.number().min(1).max(5) 
  })) 
});

Note especially the comments property, that thing looks exactly like the outer call we first make and it is the same. Nesting is as easy as that.

Node.js Express and Joi

Libraries like these are great but wouldn’t it be even better if we could use them in a more seamless way, like in a Request pipeline? Let’s have a look firstly how we would use Joi in an Express app in Node.js:

const Joi = require('joi'); 
app.post('/blog', async (req, res, next) => { 
  const { body } = req; const 
  blogSchema = Joi.object().keys({ 
    title: Joi.string().required 
    description: Joi.string().required(), 
    authorId: Joi.number().required() 
  }); 
  const result = Joi.validate(body, blogShema); 
  const { value, error } = result; 
  const valid = error == null; 
  if (!valid) { 
    res.status(422).json({ 
      message: 'Invalid request', 
      data: body 
    }) 
  } else { 
    const createdPost = await api.createPost(data); 
    res.json({ message: 'Resource created', data: createdPost }) 
  } 
});

The above works. But we have to, for each route:

  1. create a schema
  2. call validate()

It’s, for lack of a better word, lacking in elegance. We want something slick looking.

Building a middleware

Let’s see if we can’t rebuild it a bit to a middleware. Middlewares in Express is simply something we can stick into the request pipeline whenever we need it. In our case, we would want to try and verify our request and early on determine whether it is worth proceeding with it or abort it.

So let’s look at a middleware. It’s just a function right:

const handler = (req, res, next) = { // handle our request } 
const middleware = (req, res, next) => { // to be defined } 
app.post( '/blog', middleware, handler )

It would be neat if we could provide a schema to our middleware so all we had to do in the middleware function was something like this:

(req, res, next) => { 
  const result = Joi.validate(schema, data) 
}

We could create a module with a factory function and module for all our schemas. Let’s have a look at our factory function module first:

const Joi = require('joi'); 
const middleware = (schema, property) => { 
  return (req, res, next) => { 
  const { error } = Joi.validate(req.body, schema); 
  const valid = error == null; 

if (valid) {
next();
} else {
const { details } = error;
const message = details.map(i => i.message).join(',');

console.log("error", message); 

res.status(422).json({ error: message }) }
}
}
module.exports = middleware;

Let’s thereafter create a module for all our schemas, like so:

// schemas.js
const Joi = require('joi')
const schemas = {
blogPOST: Joi.object().keys({
title: Joi.string().required
description: Joi.string().required()
})
// define all the other schemas below
};
module.exports = schemas;

Ok then, let’s head back to our application file:

// app.js
const express = require('express')
const cors = require('cors');
const app = express()
const port = 3000
const schemas = require('./schemas');
const middleware = require('./middleware');
var bodyParser = require("body-parser");

app.use(cors());
app.use(bodyParser.json());
app.get('/', (req, res) => res.send('Hello World!'))
app.post('/blog', middleware(schemas.blogPOST) , (req, res) => {
console.log('/update');
res.json(req.body);
});
app.listen(port, () => console.log(Example app listening on port ${port}!))

Testing it out

There are many ways to test this out. We could do a fetch() call from a browser console or use cURL and so on. We opt for using a chrome plugin called Advanced REST Client.

Let’s try to make a POST request to /blog. Remember our schema for this route said that title and description were mandatory so let's try to crash it, let's omit title and see what happens:

Aha, we get a 422 status code and the message title is required, so Joi does what it is supposed to. Just for safety sake lets re-add title:

Ok, happy days, it works again.

Support Router and Query parameters

Ok, great we can deal with BODY in POST request what about router parameters and query parameters and what would we like to validate with them:

  • query parameters, here it makes sense to check that for example parameters like page and pageSize exist and is of type number. Imagine us doing a crazy request and our database contains a few million products, AOUCH :)
  • router parameters, here it would make sense to first off check that we are getting a number if we should get a number that is ( we could be sending GUIDs for example ) and maybe check that we are not sending something that is obviously wrong like a 0 or something

 Adding query parameters support

Ok, we know of query parameters in Express, that they reside under the request.query. So the simplest thing we could do here is to ensure our middleware.js takes another parameter, like so:

const middleware = (schema, property) => { }

and our full code for middleware.js would, therefore, look like this:

const Joi = require('joi');
const middleware = (schema, property) => {
return (req, res, next) => {
const { error } = Joi.validate(req[property], schema);
const valid = error == null;
if (valid) { next(); }
else {
const { details } = error;
const message = details.map(i => i.message).join(',')
console.log("error", message);
res.status(422).json({ error: message })
}
}
}
module.exports = middleware;

This would mean we would have to have a look at app.js and change how we invoke our middleware() function. First off our POST request would now have to look like this:

app.post(
'/blog',
middleware(schemas.blogPOST, 'body') ,
(req, res) => {
console.log('/update');
res.json(req.body);
});

As you can see we add another argument body to our middleware() call.

Let’s now add the request who’s query parameters we are interested in:

app.get(
'/products',
middleware(schemas.blogLIST, 'query'),
(req, res) => { console.log('/products');
const { page, pageSize } = req.query;
res.json(req.query);
});

As you can see all we have to do above is add the argument query. Lastly, let's have a look at our schemas.js:

// schemas.js
const Joi = require('joi');
const schemas = {
blogPOST: Joi.object().keys({
title: Joi.string().required(),
description: Joi.string().required(),
year: Joi.number() }),
blogLIST: {
page: Joi.number().required(),
pageSize: Joi.number().required()
}
};
module.exports = schemas;

As you can see above we have added the blogLIST entry.

Testing it out

Let’s head back to Advanced REST client and see what happens if we try to navigate to /products without adding the query parameters:

As you can see Joi kicks in and tells us that page is missing.

Let’s ensure page and pageSize is added to our URL and try it again:

Ok, everybody is happy again. :)

Adding router parameters support

Just like with query parameters we just need to point out where we find our parameters, in Express those reside under req.params. Thanks to the works we already did with middleware.js we just need to update our app.js with our new route entry like so:

// app.js
app.get(
'/products/:id',
middleware(schemas.blogDETAIL, 'params'),
(req, res) => {
console.log("/products/:id");
const { id } = req.params;
res.json(req.params);
}
)

At this point we need to go into schemas.js and add the blogDetail entry so schemas.js should now look like the following:

// schemas.js

const Joi = require('joi');

const schemas = {
blogPOST: Joi.object().keys({
title: Joi.string().required(),
description: Joi.string().required(),
year: Joi.number() }),
blogLIST: {
page: Joi.number().required(),
pageSize: Joi.number().required()
},
blogDETAIL: {
id: Joi.number().min(1).required()
}
};
module.exports = schemas;

Try it out

The last step is trying it out so let’s first test to navigate to /products/abc. That should throw an error, we are only OK with numbers over 0:

Ok, now for a URL stating /products/0, our other requirement:

Also, that fails, as expected.

Summary

We have introduced the validation library Joi and presented some basic features and how to use it. Lastly, we have looked at how to create a middleware for Express and use Joi in a smart way.

Originally published by Chris Noring at dev.to

=============================

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter

Learn More

☞ The Complete Node.js Developer Course (3rd Edition)

☞ Angular & NodeJS - The MEAN Stack Guide

☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

☞ Docker for Node.js Projects From a Docker Captain

☞ Intro To MySQL With Node.js - Learn To Use MySQL with Node!

☞ Node.js Absolute Beginners Guide - Learn Node From Scratch

☞ React Node FullStack - Social Network from Scratch to Deploy

☞ Selenium WebDriver - JavaScript nodeJS webdriver IO & more!

☞ Complete Next.js with React & Node - Beautiful Portfolio App

☞ Build a Blockchain & Cryptocurrency | Full-Stack Edition

Creating a RESTful Web API with Node.js and Express.js from scratch

Creating a RESTful Web API with Node.js and Express.js from scratch

In this article, I’ll show you step by step how to create a RESTful Web API with Node.js and Express.js by building a simple and useful Todo API. This article assumes you have basic javascript knowledge and terminal using capabilities.

In this article, I’ll show you step by step how to create a RESTful Web API with Node.js and Express.js by building a simple and useful Todo API. This article assumes you have basic javascript knowledge and terminal using capabilities.

You can also build a Web API in Node.js by using another framework except Express.js but Express.js is one of the most popular web framework for Node.js.

You can found the final source code of this Web API in this github repository.

Let’s start to create our mentioned Web API.

Before start

If you have never used Node.js or npm package manager you should install them.

To check whether the Node.js is already installed on your computer, open your terminal and run node -v command. If you see your Node.js version it's installed. Otherwise go to below link.

Click here to download and install Node.js (You can choose LTS version)

And if you don’t have any IDE or text editor for writing javascript I advice you Visual Studio Code.

Click here to download VS Code (Optional)

About express-generator

In fact we could use <a href="https://expressjs.com/en/starter/generator.html" target="_blank">express-generator</a> tool which designed to creating an Express Web API quickly but I want to create this API from scratch because of that tool puts some extra files and folder structures that we don't need them now. But you can use this useful tool next time on creating new Web API. I won't use it now due to keep article simple.

Creating Project

Go to your workspace root folder and create a new folder there named "todo-api".

Then create "package.json" and "server.js" files into "todo-api" folder like below.

package.json

{
    "name": "todo-api",
    "version": "1.0.0",
    "scripts": {
        "start": "node server.js"
    },
    "dependencies": {
        "express": "^4.16.4"
    }
}

server.js

const http = require('http');
const express = require('express');
const app = express();
app.use(express.json());
app.use('/', function(req, res) {
    res.send('todo api works');
});
const server = http.createServer(app);
const port = 3000;
server.listen(port);
console.debug('Server listening on port ' + port);

After creating above files open your terminal in the "todo-api" folder and run npm installcommand.

This command will be install your project dependencies which pointed at the "package.json" file.

After finished package download process, downloaded dependency files will be installed into"node_modules" folder at the root of the "todo-api" folder.

After finished package installing then run npm start to start our Web API.

Now our Web API listening. To see result open your web browser then write localhost:3000 to address bar and press enter.

As result you’ll see our request handler response in your browser: “todo api works”.

This is a dead simple Express.js Web API. And it needs the some development. For example we need to an api endpoint to get todo items. So let’s add a new API endpoint for this.

Create a new folder named "routes" in the root of the "todo-api" folder.

Then create a "items.js" file inside of "routes" folder and put following codes inside it.

Your final folder structure should be like below;

/todo-api
/node_modules
/routes
    items.js
package.json
server.js

items.js

const express = require('express');
const router = express.Router();
const data = [
    {id: 1, title: 'Finalize project', order: 1, completed: false, createdOn: new Date()},
    {id: 2, title: 'Book ticket to London', order: 2, completed: false, createdOn: new Date()},
    {id: 3, title: 'Finish last article', order: 3, completed: false, createdOn: new Date()},
    {id: 4, title: 'Get a new t-shirt', order: 4, completed: false, createdOn: new Date()},
    {id: 5, title: 'Create dinner reservation', order: 5, completed: false, createdOn: new Date()},
];
router.get('/', function (req, res) {
    res.status(200).json(data);
});
router.get('/:id', function (req, res) {
    let found = data.find(function (item) {
        return item.id === parseInt(req.params.id);
    });
    if (found) {
        res.status(200).json(found);
    } else {
        res.sendStatus(404);
    }
});
module.exports = router;

Initial code of "items.js" file contains two endpoints. First one gets all todo items and second one gets one item which matches given id parameter.

Before testing items routes we should register it in the "server.js" file.

Modify "server.js" file like below to register new item routes.

server.js

const http = require('http');
const express = require('express');
const itemsRouter = require('./routes/items');
const app = express();
app.use(express.json());
app.use('/items', itemsRouter);
app.use('/', function(req, res) {
    res.send('todo api works');
});
const server = http.createServer(app);
const port = 3000;
server.listen(port);
console.debug('Server listening on port ' + port);

Now run npm start to start our Web API.

Then open your web browser and write localhost:3000/items to address bar and press enter.

You’ll see todo items json array in the response body.

And write localhost:3000/items/3 to address bar and press enter.

You’ll see the todo item which has id 3 in the response body.

But not finished up yet.

CRUD Operations and HTTP methods

I think we’ll need CRUD operations to Create, Read, Update and Delete todo items.

We have already two endpoints for getting items. So we need Create, Update and Delete endpoints.

Let’s add also these endpoints into the items.js file.

Our final "items.js" file and endpoints should be like below.

const express = require('express');
const router = express.Router();

const data = [
  {id: 1, title: 'Finalize project',          order: 1, completed: false, createdOn: new Date()},
  {id: 2, title: 'Book ticket to London',     order: 2, completed: false, createdOn: new Date()},
  {id: 3, title: 'Finish last article',       order: 3, completed: false, createdOn: new Date()},
  {id: 4, title: 'Get a new t-shirt',         order: 4, completed: false, createdOn: new Date()},
  {id: 5, title: 'Create dinner reservation', order: 5, completed: false, createdOn: new Date()},
];

router.get('/', function (req, res) {
  res.status(200).json(data);
});

router.get('/:id', function (req, res) {
  let found = data.find(function (item) {
    return item.id === parseInt(req.params.id);
  });

  if (found) {
    res.status(200).json(found);
  } else {
    res.sendStatus(404);
  }
});

router.post('/', function (req, res) {
  let itemIds = data.map(item => item.id);
  let orderNums = data.map(item => item.order);

  let newId = itemIds.length > 0 ? Math.max.apply(Math, itemIds) + 1 : 1;
  let newOrderNum = orderNums.length > 0 ? Math.max.apply(Math, orderNums) + 1 : 1;

  let newItem = {
    id: newId,
    title: req.body.title,
    order: newOrderNum,
    completed: false,
    createdOn: new Date()
  };

  data.push(newItem);

  res.status(201).json(newItem);
});

router.put('/:id', function (req, res) {
  let found = data.find(function (item) {
    return item.id === parseInt(req.params.id);
  });

  if (found) {
    let updated = {
      id: found.id,
      title: req.body.title,
      order: req.body.order,
      completed: req.body.completed
    };

    let targetIndex = data.indexOf(found);

    data.splice(targetIndex, 1, updated);

    res.sendStatus(204);
  } else {
    res.sendStatus(404);
  }
});

router.delete('/:id', function (req, res) {
  let found = data.find(function (item) {
    return item.id === parseInt(req.params.id);
  });

  if (found) {
    let targetIndex = data.indexOf(found);

    data.splice(targetIndex, 1);
  }

  res.sendStatus(204);
});

module.exports = router;

Short Explanation

I wanna explain shortly some points of our last codes.

First of all you must have noticed that our api works on a static data and keeps it on memory. All of our GET, POST, PUT and DELETE http methods just manipulate a json array. The purpose of this is to keep article simple and draw attention to the Web API structure.

Due to this situation our POST method has some extra logic such as calculating next item ids and order numbers.

So you can modify logic and data structures in these http methods to use a database or whatever you want.

Testing API with Postman

We have tested the GET methods of our Web API in our web browser and seen responses. But we can’t test directly POST, PUT and DELETE http methods in web browser.

If you want to test also other http methods you should use Postman or another http utility.

Now I’ll show you how to test the Web API with Postman

Before we start click here and install Postman.

When you first launch Postman after installing you’ll see start window. Close this start window by clicking close button on top right corner. Then you must see following screen.

An empty Postman request

Sending GET Request

Before sending a request to API we should start it by running npm startcommand as we do before.

After start the Web API and seeing “Server listening on…” message write localhost:3000/itemsto address bar as seen below and click Send button. You'll see todo items array as API response like below.

Sending a GET request with Postman

You can try similarly by giving an item id in request url like this localhost:3000/items/3

Sending POST Request

To sending a POST request and create a new todo item write localhost:3000/items to address bar and change HTTP verb to POST by clicking arrow at front of the address bar as seen below.

Sending a POST request with Postman

Before sending the POST request you should add request data to body of the request by clicking body tab and selecting raw and JSON as seen below.

Attaching a JSON body to POST request in Postman

Now click Send button to send POST request to the Web API. Then you must get “201 Created” http response code and seeing created item in the response body.

To see the last status of todo items send a get request to localhost:3000/itemsaddress. You must see newly created item at the end of the list.

Sending PUT Request

Sending PUT request is very similar to sending POST request.

The most obvious difference is request url should be pointed specific item like this localhost:3000/items/3

And you should choose PUT as http verb instead of POST and send all of the required data in the request body unlike POST.

For example you could send a JSON body in the PUT request as below.

An example JSON body for PUT request

{
    "title": "New title of todo item",
    "order": 3,
    "completed": false
}

When you click Send button you must get “204 No Content” http response code. You can check item you updated by sending a get request.

Sending DELETE Request

To send a DELETE request, change the request url to address a specific item id like this localhost:3000/items/3

And select DELETE as http verb and click Send button.

You must get “204 No Content” http response code as result of the DELETE operation.

Send a get request and see the last status of list.

About the DELETE Http Request

I want to say a few words about DELETE http request. You must have noticed something in our delete code. DELETE request returns “204 No Content” every situation.

Http DELETE requests are idempotent. So what that mean? If you delete a resource on server by sending DELETE request, it’s removed from the collection. And every next DELETE request on the same resource won’t change outcome. So you won’t get “404 Not Found” in the second request. Each request returns same response whether succeed or not. That’s mean idempotent operation.

Conclusion

Finally we’ve tested all http methods of our Web API.

As you can see, it works just fine.

Thanks for reading ❤

If you liked this post, share it with all of your programming buddies!

Node.js Express FrameWork Tutorial - Learn Express Framework

Node.js Express FrameWork Tutorial - Learn Express Framework

In this tutorial, we will study the Express framework. This framework is built in such a way that it acts as a minimal and flexible Node.js web application framework, providing a robust set of features for building single and multipage, and hybrid web application.

Originally published at https://www.guru99.com

In Node.js Express FrameWork tutorial, you will learn:

  • What is Express.js?
  • Installing and using Express
  • What are Routes?
  • Sample Web server using express.js
What is Express.js?

Express.js is a Node js web application server framework, which is specifically designed for building single-page, multi-page, and hybrid web applications.

It has become the standard server framework for node.js. Express is the backend part of something known as the MEAN stack.

The MEAN is a free and open-source JavaScript software stack for building dynamic web sites and web applications which has the following components;

1) MongoDB - The standard NoSQL database

2) Express.js - The default web applications framework

3) Angular.js - The JavaScript MVC framework used for web applications

4) Node.js - Framework used for scalable server-side and networking applications.

The Express.js framework makes it very easy to develop an application which can be used to handle multiple types of requests like the GET, PUT, and POST and DELETE requests.

Installing and using Express

Express gets installed via the Node Package Manager. This can be done by executing the following line in the command line

npm install express

The above command requests the Node package manager to download the required express modules and install them accordingly.

Let's use our newly installed Express framework and create a simple "Hello World" application.

Our application is going to create a simple server module which will listen on port number 3000. In our example, if a request is made through the browser on this port number, then server application will send a 'Hello' World' response to the client. 

var express=require('express');
var app=express();
app.get('/',function(req,res)
{
res.send('Hello World!');
});
var server=app.listen(3000,function() {});

Code Explanation:

  1. In our first line of code, we are using the require function to include the "express module."
  2. Before we can start using the express module, we need to make an object of it.
  3. Here we are creating a callback function. This function will be called whenever anybody browses to the root of our web application which is http://localhost:3000 . The callback function will be used to send the string 'Hello World' to the web page.
  4. In the callback function, we are sending the string "Hello World" back to the client. The 'res' parameter is used to send content back to the web page. This 'res' parameter is something that is provided by the 'request' module to enable one to send content back to the web page.
  5. We are then using the listen to function to make our server application listen to client requests on port no 3000. You can specify any available port over here.

If the command is executed successfully, the following Output will be shown when you run your code in the browser.

Output:

From the output,

  • You can clearly see that we if browse to the URL of localhost on port 3000, you will see the string 'Hello World' displayed on the page.
  • Because in our code we have mentioned specifically for the server to listen on port no 3000, we are able to view the output when browsing to this URL.
What are Routes?

Routing determine the way in which an application responds to a client request to a particular endpoint.

For example, a client can make a GET, POST, PUT or DELETE http request for various URL such as the ones shown below;

http://localhost:3000/Books
http://localhost:3000/Students

In the above example,

  • If a GET request is made for the first URL, then the response should ideally be a list of books.
  • If the GET request is made for the second URL, then the response should ideally be a list of Students.
  • So based on the URL which is accessed, a different functionality on the webserver will be invoked, and accordingly, the response will be sent to the client. This is the concept of routing.

Each route can have one or more handler functions, which are executed when the route is matched.

The general syntax for a route is shown below

app.METHOD(PATH, HANDLER)

Wherein,

1) app is an instance of the express module

2) METHOD is an HTTP request method (GET, POST, PUT or DELETE)

3) PATH is a path on the server.

4) HANDLER is the function executed when the route is matched.

Let's look at an example of how we can implement routes in the express. Our example will create 3 routes as

  1. A /Node route which will display the string "Tutorial on Node" if this route is accessed
  2. A /Angular route which will display the string "Tutorial on Angular" if this route is accessed
  3. A default route / which will display the string "Welcome to Guru99 Tutorials."

Our basic code will remain the same as previous examples. The below snippet is an add-on to showcase how routing is implemented. 

var express = require('express');
var app = express();
app.route('/Node',get(function(req,res)
{
    res.send("Tutorial on Node");
});
post(function(req,res)
{
    res.send("Tutorial on Angular");
});
put(function(req,res)
{
    res.send('Welcome to Guru99 Tutorials');
}));

Code Explanation:

  1. Here we are defining a route if the URL http://localhost:3000/Node is selected in the browser. To the route, we are attaching a callback function which will be called when we browse to the Node URL.
  2. The function has 2 parameters.
  • The main parameter we will be using is the 'res' parameter, which can be used to send information back to the client.
  • The 'req' parameter has information about the request being made. Sometimes additional parameters could be sent as part of the request being made, and hence the 'req' parameter can be used to find the additional parameters being sent.
  1. We are using the send function to send the string "Tutorial on Node" back to the client if the Node route is chosen.
  2. Here we are defining a route if the URL http://localhost:3000/Angular is selected in the browser. To the route, we are attaching a callback function which will be called when we browse to the Angular URL.
  3. We are using the send function to send the string "Tutorial on Angular" back to the client if the Angular route is chosen.
  4. This is the default route which is chosen when one browses to the route of the application – http://localhost:3000. When the default route is chosen, the message "Welcome to Guru99 Tutorials" will be sent to the client.

If the command is executed successfully, the following Output will be shown when you run your code in the browser.

Output:

From the output,

  • You can clearly see that we if browse to the URL of localhost on port 3000, you will see the string 'Welcome to Guru99 Tutorials' displayed on the page.
  • Because in our code, we have mentioned that our default URL would display this message.

From the output,

  • You can see that if the URL has been changed to /Node, the respective Node route would be chosen and the string "Tutorial On Node' is displayed.

From the output,

  • You can see that if the URL has been changed to /Angular, the respective Node route would be chosen and the string "Tutorial On Angular" is displayed.
Sample Web server using express.js

From our above example, we have seen how we can decide on what output to show based on routing. This sort of routing is what is used in most modern-day web applications. The other part of a web server is about using templates in Node js.

When creating quick on-the-fly Node applications, an easy and fast way is to use templates for the application. There are many frameworks available in the market for making templates. In our case, we will take the example of the jade framework for templating.

Jade gets installed via the Node Package manager. This can be done by executing the following line in the command line

npm install jade

The above command requests the Node package manager to download the required jade modules and install them accordingly.

NOTE: In the latest version of Node jade has been deprecated. Instead, use pug.

Let's use our newly installed jade framework and create some basic templates.

Step 1) The first step is to create a jade template. Create a file called index.jade and insert the below code. Ensure to create the file in "view" folder 

  1. Here we are specifying that the title of the page will be changed to whatever value is passed when this template gets invoked.
  2. We are also specifying that the text in the header tag will get replaced to whatever gets passed in the jade template.

var express=require('express');
var app=express();
app.set('view engine','jade');
app.get('/',function(req,res)
{
res.render('index',
{title:'Guru99',message:'Welcome'})
});
var server=app.listen(3000,function() {});

Code Explanation:

  1. The first thing to specify in the application is "view engine" that will be used to render the templates. Since we are going to use jade to render our templates, we specify this accordingly.
  2. The render function is used to render a web page. In our example, we are rendering the template (index.jade) which was created earlier.
  3. We are passing the values of "Guru99" and "Welcome" to the parameters "title" and "message" respectively. These values will be replaced by the 'title', and 'message' parameters declared in the index.jade template.

If the command is executed successfully, the following Output will be shown when you run your code in the browser.

Output:

From the output,

  • We can see that the title of the page gets set to "Guru99" and the header of the page gets set to "Welcome."
  • This is because of the jade template which gets invoked in our node js application.

Summary

  • The express framework is the most common framework used for developing Node js applications. The express framework is built on top of the node.js framework and helps in fast-tracking development of server-based applications.
  • Routes are used to divert users to different parts of the web applications based on the request made. The response for each route can be varied depending on what needs to be shown to the user.
  • Templates can be used to inject content in an efficient manner. Jade is one of the most popular templating engines used in Node.js applications.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

Best 50 Nodejs interview questions from Beginners to Advanced in 2019

Node.js 12: The future of server-side JavaScript

Getting Started With Express

MongoDB, Express, Vue.js 2, Node.js (MEVN) and SocketIO Chat App

WebSocket + Node.js + Express — Step by step tutorial using Typescript