#5 Pure NodeJs: Routing (Part 5)
Published: 2024-02-12 04:40:31

In the previous  tutorials i showed you how to return html ,Json, and plain text as response to nodejs server but all that was on the root route of the application to [localhost:2121](http://localhost:2121/) in this tutorial we will handle multi routes to serve different type of data in different routes.

programs and versions: 
nodejs: v18.19.0
npm:    v10.2.3
vscode: v1.85.2

should work on any nodejs > 14
### Lets Start:
first we will use the previous server code:

```javascript
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end('<h1>Hello World!</h1>');
});

const PORT = 2121;
server.listen(PORT, 'localhost', () => {
  console.log(`server run on port ${PORT}`);
});

```

first we will move the createServer callback function like this: 

```javascript
//server.js
const listener = (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end('<h1>Hello World!</h1>');
};

const server = http.createServer(listener);
```
now we will create routes object: 
```javascript
//server.js
const getHeaders = (type) => ({
  'Content-Type': type,
});

const routes = {
  '/text': (req, res) => {
    res.writeHead(200, getHeaders('text/plain'));
    res.end('hello world!');
  },
  '/json': (req, res) => {
    res.writeHead(200, getHeaders('application/json'));
    res.end(JSON.stringify({ res: 'hello world' }));
  },
};
```
notice that we create function getHeaders that take content type as parameter and return the header object because we will use it in all routes handler functions.

as you can see we created two routes /json and /text that will return the plain text and json data. now i will add html file and error page to be redirected to if the route not found.
```javascript 
//server.js
const htmlHandler = (req, res) => {
  fs.readFile('index.html', function (err, data) {
    res.writeHead(200, getHeaders('text/html'));
    res.end(data);
  });
};
const errorHandler = (req, res) => {
  res.writeHead(404, getHeaders('application/json'));
  res.end(JSON.stringify({ res: 'Not Found' }));
};
const routes = {
...
 '/html': htmlHandler,
 '/': htmlHandler,
 '/error': errorHandler,
....
}
```
as you can see we created two handlers for the html and the error because we can reuse it in different routes as we use the html in the root "/" route and in the "/html' route

now to use this routes we need to modifies the listener function:
```javascript
//server.js
const listener = (req, res) => {
  const route = req.url.split('?')[0].split('/')[1];

  const handler = routes[`/${route}`] || routes['/error'];

  handler(req, res);
};
```
We can access the request URL from the 'req' object. I split the URL at the '?' to obtain the URL without any query parameters. For example, '/html?foo=bar' will now return only '/html.' I then use another split operation to extract just the first route. Consequently, if the URL is '/html/1,' it will only return 'html' in the handler constant. In the handler constant, I'm attempting to retrieve the route handler from the 'routes' object. I would like to highlight that I added a '/' before the '${route}' to align with the 'routes' object. if the route is in the object it will route that route handler function if not it will return the error handler 

you can run and test the server:
```shell
//server.js is the file we work on it 
node server.js
```
now you can open [localhost:2121](http://localhost:2121/) and test the routes:
[html](http://localhost:2121/html)
[text](http://localhost:2121/text)
[json](http://localhost:2121/json)

### the complete code:
```javascript
const http = require('http');
const fs = require('fs');

const getHeaders = (type) => ({
  'Content-Type': type,
});
const htmlHandler = (req, res) => {
  fs.readFile('index.html', function (err, data) {
    res.writeHead(200, getHeaders('text/html'));
    res.end(data);
  });
};
const errorHandler = (req, res) => {
  res.writeHead(404, getHeaders('application/json'));
  res.end(JSON.stringify({ res: 'Not Found' }));
};

const routes = {
  '/text': (req, res) => {
    res.writeHead(200, getHeaders('text/plain'));
    res.end('hello world!');
  },
  '/json': (req, res) => {
    res.writeHead(200, getHeaders('application/json'));
    res.end(JSON.stringify({ res: 'hello world' }));
  },
  '/html': htmlHandler,
  '/': htmlHandler,
  '/error': errorHandler,
};
const listener = (req, res) => {
  const route = req.url.split('?')?.[0].split('/')?.[1];

  const handler = routes?.[`/${route}`] || routes['/error'];

  handler(req, res);
};

const server = http.createServer(listener);

const PORT = 2121;
const HOST = 'localhost';
server.listen(PORT, HOST, () => {
  console.log(`server run on port http://${HOST}:${PORT}`);
});

```
side note: in the html route i used html file like we did in the Previous article [#3 Pure NodeJs: return html file (Part 3)](https://dev.to/basharosman/3-pure-nodejs-return-html-file-part-3-5dd2) so you should create html file in the same directory as the server.js file.

### Conclusion:
In this article, we demonstrate how to manage various routes. In the upcoming article, we will also address the process of serving images.