Node.js Basics — Handle Complex HTTP Requests

John Au-Yeung - Jan 22 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Node.js is a popular runtime platform to create programs that run on it.

It lets us run JavaScript outside the browser.

In this article, we’ll look at how to start using Node.js to create programs.

Complex Routing

It’s easy to do simple routing with our own code with our own HTTP server, but if we want to add more complex routing, then we can use the router module to help us do this.

To use it, we install the router and finalhandler packages by running:

npm i router finalhandler
Enter fullscreen mode Exit fullscreen mode

to install the packages.

Then we can use it to handle requests by writing:

const finalhandler = require('finalhandler')
const http = require('http')
const Router = require('router')

const router = Router()
router.get('/', (req, res) => {
  res.setHeader('Content-Type', 'text/plain; charset=utf-8')
  res.end('Hello World!')
})

const server = http.createServer((req, res) => {
  router(req, res, finalhandler(req, res))
})

server.listen(8080)
Enter fullscreen mode Exit fullscreen mode

We create the Router instance and then call the get method on it to create a GET route to let us handle GET requests to the / route.

The res.setHeader method lets us set the response header.

And the res.end method lets us set the response body.

To accept URL parameters, we can write:

const finalhandler = require('finalhandler')
const http = require('http')
const Router = require('router')

const router = Router({ mergeParams: true })
router.route('/pet/:id')
  .get(function (req, res) {
    res.setHeader('Content-Type', 'application/json')
    res.end(JSON.stringify({ name: 'tobi', id: req.params.id }))
  })
  .delete(function (req, res) {
    res.end()
  })
  .all(function (req, res) {
    res.statusCode = 405
    res.end()
  })

const server = http.createServer((req, res) => {
  router(req, res, finalhandler(req, res))
})

server.listen(8080)
Enter fullscreen mode Exit fullscreen mode

We pass in an object to the Router function with the mergParams property set to true so that we can accept URL parameters.

Then we can use the route method to define routes that takes the id parameter.

The :id substring is the URL parameter placeholder for the id parameter.

Then we call res.setHeader to set the header.

And we use the req.params.id property to get the value of the id URL parameter.

We set the res.statusCode property to set the response status code.

The delete method lets us define a route to handle a DELETE request.

We can also add a middleware that runs before our routes run.

For example, we can write:

const finalhandler = require('finalhandler')
const http = require('http')
const Router = require('router')

const router = Router({
  mergeParams: true
})
router.use(function(request, response, next) {
  console.log('middleware executed');
  next(null);
});
router.route('/pet/:id')
  .get(function(req, res) {
    res.setHeader('Content-Type', 'application/json')
    res.end(JSON.stringify({
      name: 'tobi',
      id: req.params.id
    }))
  })
  .delete(function(req, res) {
    res.end()
  })
  .all(function(req, res) {
    res.statusCode = 405
    res.end()
  })

const server = http.createServer((req, res) => {
  router(req, res, finalhandler(req, res))
})

server.listen(8080)
Enter fullscreen mode Exit fullscreen mode

We call the use method with a function. This function is called before any route handler is called.

Therefore, we should see 'middleware executed' string logged in the console.

The next function lets us call the route handler.

Conclusion

We can create more complex route handlers for our HTTP server with the router package.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .