About a year ago, I tried Next.js for the first time and was so impressed by their file-based routing that I decided to implement a similar system on the backend. I couldn't find anything suitable, so I took it upon myself to create my own solution. It turned out to be technology-agnostic and works with both pure Node.js and the popular Express.js.
In this brief guide, we will attempt to partially implement a shop's API. This tutorial uses JavaScript and CommonJS module types to keep things simple and quick to get started.
๐ฟ Install node-file-router:
npm install node-file-router
Create a server.js
file and do the following:
If you use pure Node.js:
// 1. Import default http module and node-file-router
const http = require('node:http');
const { initFileRouter } = require('node-file-router');
// 2. Create an entry-point function
async function run() {
// 3. Initialize node-file-router and the handler function
const useFileRouter = await initFileRouter();
const server = http.createServer((req, res) => {
// 4. Create a server and invoke created function on each request
useFileRouter(req, res);
});
// 5. Start listening a server on 4000 port
const port = 4000;
server.listen(port, () =>
console.log(`Server running at http://localhost:${port}/`)
);
}
// 6. Run entry-point function
run();
If you use Express.js:
const { initFileRouter } = require('node-file-router');
const express = require('express');
async function run() {
const fileRouter = await initFileRouter();
const app = express();
app.listen(4000);
app.use(fileRouter);
}
run();
๐ก We will create a home route that displays welcome content.
1. Create an api
folder at the root of your project.
โโโ api/ <-
โโโ server.js
โโโ package.json
2. Create a file named index.js
inside this folder:
โโโ api/
โ โโโ index.js <-
โโโ server.js
โโโ package.json
module.exports = function index(req, res) {
res.end("Welcome to our shop!");
}
3. Run a server using: node server.js
command 4. Open a browser and navigate to http://localhost:4000. You should see the message Welcome to our shop!
displayed.
Congratulations! ๐ You've created a first file route
1. Before we start, we need a small utility function that will parse JSON from a request. Create a folder utils
and put http.utils.js
the file inside.
โโโ api/
โโโ ...
โโโ utils/
โ โโโ http.utils.js <-
...
module.exports = {
parseJson(request) {
return new Promise((resolve, reject) => {
let data = '';
request.on('data', (chunk) => {
data += chunk;
});
request.on('end', () => {
try {
const parsedData = JSON.parse(data);
resolve(parsedData);
} catch (e) {
reject(e);
}
});
});
}
}
2. Create a folder called products
and an index.js
file inside it.
โโโ api/
โ โโโ products/ <-
โ โ โโโ index.js <-
โ โโโ ...
...
3. Implement get
and post
methods:
const { parseJson } = require('../../utils/http.utils');
module.exports = {
get: (req, res) => {
res.end('list of products');
},
post: async (req, res) => {
const newProduct = await parseJson(req);
res.end(`a product will be created: ${JSON.stringify(newProduct)}`);
}
}
3. Open a browser and go to http://localhost:4000/products. You should see a list of products
message displayed.
4. Make a POST request using curl
, Postman
or any tool you like on http://localhost:4000/products. The response should display a product will be created
along with your content.
Perfect! ๐ Let's move on
1. Create a new file with the name [id]
inside the product
folder.
โโโ api/
โ โโโ products/
โ โ โโโ ...
โ โ โโโ [id].js <-
โ โโโ index.js
...
2. Fill it the same way as you did before:
module.exports = {
// Add the `routeParams` argument as the final argument to the function. This argument will contain
// all the taken route parameters.
get: (req, res, routeParams) => {
const { id } = routeParams;
res.end(`product ${id} info`);
}
};
3. Open a browser and go to http://localhost:4000/products/123. <br/>
The page should display a message: product 123
.
Alright, let's make it more sophisticated.
Say, we want to address the following case: /catalog/tag-1/tag-2/tag-n
4. Create a catalog
folder with [[...categories]].js
inside.
โโโ api/
โ โโโ catalog/
โ โ โโโ ...
โ โ โโโ [[...categories]].js <-
โ โโโ index.js
...
And add a single get
method:
module.exports = {
get: (req, res, routeParams) => {
const { categories } = routeParams;
// This type of route also covers just "/catalog"
if (!categories) {
return res.end('all products');
}
res.end(`get products that have such tags: ${categories}`);
},
};
5. Open a browser and go to http://localhost:4000/catalog/men/sneakers/nike. The page should display a list of categories: men, sneakers, Nike.
๐ฅ That's it!