A simple and flexible router wrapper for Fastify, allowing you to easily add routes and middlewares in a structured manner.
To install the package, use npm or yarn:
npm install @wistle/router
First, create a server instance and start it. The following code shows how to start the Fastify server.
// app.js
import { Server } from './lib/server';
(async () => {
try {
await new Server().start();
} catch (err) {
console.error("Wistle Router: error on server start", err);
process.exit(1);
}
})();
Define your controller methods, which will handle the incoming requests.
// controllers/HealthCheckController.js
class HealthCheckController {
async check(req, res) {
res.send({ status: "OK" });
}
async fail(req, res) {
res.status(400).send({ status: "FAIL" });
}
}
module.exports = HealthCheckController;
Extend the Router
class to define your routes and apply middlewares if needed.
// routes/HealthCheckRouter.js
const { Router } = require('@wistle/router');
const HealthCheckController = require('../controllers/HealthCheckController');
class HealthCheckRouter extends Router {
route = "/health"; // Base path for all routes in this router
setRoutes() {
const controller = new HealthCheckController();
this.addRoute("GET", "/check", controller.check);
this.addRoute("POST", "/fail", controller.fail);
}
}
module.exports = HealthCheckRouter;
Register the router with your Fastify instance. This can be done in the server setup file.
You can define and use middleware functions to process requests before they reach your controllers.
// middlewares/logRequest.js
function logRequest(req, res, next) {
console.log(`Request received: ${req.method} ${req.url}`);
next();
}
module.exports = logRequest;
Apply middleware to the router or specific routes:
// routes/HealthCheckRouter.js
const { Router } = require('@wistle/router');
const HealthCheckController = require('../controllers/HealthCheckController');
const logRequest = require('../middlewares/logRequest');
class HealthCheckRouter extends Router {
route = "/health";
middleWares = [logRequest]; // Apply middleware to all routes in this router
initRoutes() {
const controller = new HealthCheckController();
this.addRoute("GET", "/check", controller.check, [logRequest]); // Apply middleware to a specific route
this.addRoute("POST", "/fail", controller.fail);
}
}
module.exports = HealthCheckRouter;
// routes/index.js
const HealthCheckRouter = require('./HealthCheckRouter');
const Routes = [
HealthCheckRouter
];
module.exports = {
Routes
}
node app.js
In the server setup, you have the option to specify a custom initializer function that can be used to initialize any database or cache-related operations asynchronously. This function should be located at /config/initializer
and should export an async function.
Here's how to set it up:
Create a file at /config/initializer.js
(or .ts
for TypeScript) and export an async function that handles your initialization logic httpServer
is optional node http module param to handle socket connections.
// config/initializer.js
module.exports = async function customInit(httpServer) {
// Example: Initialize database connection
await initializeDatabase();
// Example: Initialize cache
await initializeCache();
console.log('Custom initialization completed.');
};
// Example functions (implement your actual initialization logic)
async function initializeDatabase() {
// Database initialization logic
console.log('Database initialized.');
}
async function initializeCache() {
// Cache initialization logic
console.log('Cache initialized.');
}
In your server setup, you have the flexibility to define a custom graceful shutdown function to handle cleanup tasks such as closing database connections or releasing resources. This function should be located at /config/grace
and should export a function.
Here's how to set it up:
Create a file at /config/grace.js
(or .ts
for TypeScript) and export a function that performs your cleanup tasks asynchronously.
// config/grace.js
module.exports = async function customGraceShutdown() {
// Example: Close database connections
await closeDatabaseConnection();
// Example: Clean up resources
await cleanupResources();
console.log('Custom graceful shutdown completed.');
};
// Example functions (implement your actual cleanup logic)
async function closeDatabaseConnection() {
// Database connection closing logic
console.log('Closing database connection.');
}
async function cleanupResources() {
// Resource cleanup logic
console.log('Cleaning up resources.');
}
In this package server setup,there is a logic to execute the custom graceful shutdown function when handling shutdown signals like SIGINT
or SIGTERM
.
Please refer @wistle/logger
for logging Docs.
Logger is global object.
Simply refer below snippet anywhere in code after Server.start()
:
Logger.verbose(operationId, message, params, param2, ...)
use config.json
(Prod) or config_dev.json
file at the root folder.
{
"port": 3000,
"trustProxy": true,
"connectionTimeout": 30000,
"keepAliveTimeout": 72000,
"headersTimeout": 60000,
"cors": {
"origin": "*",
"methods": ["GET", "POST", "PUT", "DELETE"],
"allowedHeaders": ["Content-Type", "Authorization", "wistle-operation-id"],
"credentials": true
},
"logger": {
"writeToConsole": true,
"writeToFile": false,
"writeToElk": false,
"elkOptions": { },
"fileOptions": {
"fileName": "test.log",
"flags": "a"
},
"label": "wistle-user-api"
}
}
This project is licensed under the MIT License.