Skip to main content

Usage Guide

Initialization

  1. To initialize all routes, invoke the initFileRouter function. This is an asynchronous function that constructs a table of URL patterns and creates a function that calls the matched file.
  2. Call the created function on each request, passing in the request, response, and any other necessary parameters.
import * as http from 'node:http';
import { initFileRouter } from 'node-file-router';

const useFileRouter = await initFileRouter();

const server = http.createServer((req, res) => {
useFileRouter(req, res);
// ... your code below
});
Note

The information described below pertains only to the default Node.js incoming/outgoing message interfaces, and works for both the default HTTP server and Express.js. If you use sockets, a different framework, etc., you will need to create a custom adapter.

For each incoming HTTP request, the library takes the URL and attempts to match it with a corresponding file in your application. For example, a request with the URL /users/123/orders/456 will invoke the /users/[productId]/orders/[orderId].js file.

Great news!

It works with any popular types: ts, js, cjs, and mjs.

Configuration

Source of Files

name: baseDir, default value: ./api

Set the destination path for the folder that the library will scan during requests. By default, the api folder is used.

const useFileRouter = await initFileRouter({
baseDir: 'routes'
});

The relative path is related to the current working directory of the Node.js process.

Ignoring Files by Pattern

name: ignoreFilesRegex, default value: []

To ignore certain folders and files, you can use regular expressions in the ignoreFilesRegex property. This is useful for ignoring tests or any internal functionality that you don't want to include.

const useFileRouter = await initFileRouter({
ignoreFilesRegex: [/^_.*$/, /.\.some-spec/]
});

Clear Import Cache

name: cleanImportCache, default value: false
env: works only with CommonJS modules for now

By default, Node.js caches the imported files. This means that if you change route handler files during runtime, the changes will not be applied even if you initialize the file router.

To avoid this, you can enable the clearImportCache option and reinitialize the router. It will clean the cache before importing a file.

For example:

let useFileRouter = await initFileRouter();

const server = http.createServer(async (req, res) => {
if (req.url === '/refresh') {
useFileRouter = await initFileRouter({ clearImportCache: true });
res.end('done');
return;
}

useFileRouter(req, res);
});

Methods Routing

The library offers various options for routing methods.

Note

Anything that is passed into useFileRouter will not be mutated. Route parameters are always passed as the last argument. For instance, in Express.js, it will be: function(req, res, next, routeParams).

Any Method

The function will be invoked for any request method, such as GET, POST, PATCH, and so on.

export default function(req, res, routeParams) {
// Take dynamic route params from the last argument
}

Get the route params from dynamic paths in the last argument. For instance, in this file /users/[productId]/orders/[orderId].js these params are available: { productId, orderId }. More details are described on the route matching part.

Object with Methods

Specify functions for each method in the object. The rules for nested functions are identical, with the only difference being that they belong to the method. Any method that does not list a function will result in a 404 error.

export default {
get(req, res, routeParams) {
const { documentId, draftId } = routeParams;
res.end(`Requested document ${documentId} and his draft ${draftId}`);
},
post(req, res, routeParams) {
const { documentId, draftId } = routeParams;
res.end(`Created draft ${draftId} for document ${documentId}`);
},
patch(req, res, routeParams) {
// ...
},
}

Methods in Filenames

Use the .[method]. suffix to directly specify methods in the filenames. This approach can be used for all types of routes.

Plain routes:

├── user/
│ ├── login.[post].js
│ └── logout.[post].js
...

Exact slug:

├── drafts/
│ ├── [id].[post].js
│ └── [id].[get].js
...

Catch all:

├── catalog/
│ └── [...categories].[get].js
...

Optional catch all:

├── tags/
│ └── [[...ids]].[post].js
...

Index files:

├── auth/
│ └── index.[post].js
...

The content of the file is represented as a function:

export default function(req, res, routeParams) {
// ... your code
}