Node.js Basics — Handle Complex HTTP Requests
Tags: node, webdev, programming, javascript
Published: 2021-01-22 21:32:05

**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
```

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)
```

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)
```

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)
```

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.