Skip to content

Instantly share code, notes, and snippets.

@itsRems
Last active June 21, 2022 14:44
Show Gist options
  • Save itsRems/20d072d319dccb96f3f262fd0a3ba6c4 to your computer and use it in GitHub Desktop.
Save itsRems/20d072d319dccb96f3f262fd0a3ba6c4 to your computer and use it in GitHub Desktop.
Fastify route loader
import { FastifyInstance, RouteOptions } from "fastify";
import { join } from "path";
import { walk } from "walk";
export async function registerRoutes(server: FastifyInstance, routesDir: string = 'routes') {
return await new Promise((resolve) => {
const path = join(`${__dirname}/${routesDir}`);
const files: string[] = [];
const walker = walk(path);
walker.on('file', (root, { name }, next) => {
files.push(join(`${root}/${name}`));
next();
});
walker.on('end', () => {
for (const file of files) {
const routes = require(file);
Object.keys(routes).forEach((key) => {
let route: RouteOptions = routes[key];
if (!route || !route.method || !route.handler || !route.url) return;
route = route as RouteOptions;
let clean = file.replace(join(`${__dirname}/routes/`), '');
clean = clean.substring(0, clean.lastIndexOf('.'));
route.url = `/${clean}${route.url.startsWith('/') ? '' : '/'}${route.url}`;
route.url = route.url.replace(/\\/g, '/');
const paths = route.url.split('/');
const cPaths: string[] = [];
for (let path of paths) {
if (path.startsWith('[') && path.endsWith(']')) cPaths.push(`:${path.slice(1, path.length - 1)}`);
else cPaths.push(path);
}
route.url = cPaths.join('/');
if (route.url.includes('/index/')) route.url = route.url.replace('/index/', '/');
if (route.url.endsWith('/')) route.url = route.url.slice(0, route.url.length - 1);
if (route.url.length < 1) route.url = '/';
server.route(routes[key]);
});
}
return resolve(true);
});
});
}
/**
* Loading routes:
* name will made up of [filePath (under routes)] + route url
* Just export your routes from your files (const name doesn't matter) with the "RouteOptions" fastify type.
* Ex route below !
* PS: supports parameter routing, for /test/:param/lol write /test/[param]/lol.ts
*/
/**
* For this route to be /home/hello, the route would need to be exported from a file named "home.[ts/js]" under the "routes" directory
*/
export const helloRoute: RouteOptions = {
method: 'GET',
url: '/hello',
handler: async function (req, res) {
const { lol } = req.query as any;
if (lol) return res.status(400).send({ error: 'lol not allowed !'});
return { message: "Hey there !" }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment