@piggly/fastify-chassis
Version:
An ESM/CommonJS toolkit to help you to do common operations in your back-end applications with Fastify and NodeJS.
195 lines • 6.22 kB
JavaScript
import { LoggerService, RuntimeError, DomainError, } from '@piggly/ddd-toolkit';
import debug from 'debug';
import { EnvironmentService } from '../../services/index.js';
import { HttpServer } from '../../www/HttpServer.js';
/**
* @file The API server.
* @copyright Piggly Lab 2023
*/
export class AbstractServer {
/**
* The Fastify application.
*
* @protected
* @memberof ApiServer
* @since 1.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
_app;
/**
* The options.
*
* @protected
* @memberof ApiServer
* @since 1.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
_options;
/**
* Create a new API server.
*
* @param options The options.
* @public
* @constructor
* @memberof ApiServer
* @since 1.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
constructor(options, app) {
this._options = options;
this._app = app;
}
/**
* Bootstrap the API server.
*
* This method will prepare the environment, the logger,
* the plugins and the routes for fastify.
*
* After that, it will return a new HttpServer instance.
* This instance will be used to start the server.
*
* @public
* @async
* @memberof ApiServer
* @since 1.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
async bootstrap() {
if (this._options.hooks.beforeInit) {
await this._options.hooks.beforeInit(this._app, this._options.env);
}
await this.init();
if (this._options.hooks.afterInit) {
await this._options.hooks.afterInit(this._app, this._options.env);
}
return new HttpServer(this);
}
/**
* Get the Fastify application.
*
* @public
* @memberof ApiServer
* @since 1.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
getApp() {
return this._app;
}
/**
* Get the global environment.
*
* @public
* @memberof ApiServer
* @since 1.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
getEnv() {
return this._options.env;
}
/**
* Initialize the API server.
*
* @protected
* @memberof ApiServer
* @since 1.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
async init() {
if (this._options.logger) {
debug('http:server')('Registering logger');
LoggerService.register(this._options.logger);
}
debug('http:server')('Registering environment service');
EnvironmentService.register(new EnvironmentService(this._options.env));
// Plugins
debug('http:server')('Applying plugins');
await this._options.plugins.apply(this._app, this._options.env);
// Routes
debug('http:server')('Applying routes');
await this._options.routes.apply(this._app, this._options.env);
// Not found routes
debug('http:server')('Setting not found handler');
this._app.setNotFoundHandler((request, reply) => {
debug('http:server')('🆘 [404] NOT FOUND', {
method: request.method,
url: request.url,
});
reply
.status(404)
.send(this._options.errors.notFound.toJSON(['extra']));
});
// Any error
debug('http:server')('Setting error handler');
this._app.setErrorHandler((error, request, reply) => {
const hidden = this._options.env.debug
? []
: ['extra'];
if (error instanceof DomainError) {
const _error = error.toJSON(hidden);
debug('http:server')('🆘 DOMAIN ERROR', _error);
LoggerService.softResolve().debug('UNCAUGHT_DOMAIN_ERROR', error);
return reply.status(error.status).send(_error);
}
if (error instanceof RuntimeError) {
const _error = error.toJSON(hidden);
debug('http:server')('🆘 RUNTIME ERROR', _error);
LoggerService.softResolve().debug('UNCAUGHT_RUNTIME_ERROR', error);
return reply.status(error.status).send(_error);
}
debug('http:server')('🆘 UNKNOWN ERROR', {
message: error.message,
name: error.name,
stack: error.stack,
});
LoggerService.softResolve().error('UNCAUGHT_ERROR', error);
if (this._options.errors.handler) {
this._options.errors.handler(error);
}
return reply
.status(500)
.send(this._options.errors.unknown.toJSON(hidden));
});
}
/**
* Get the default logger configuration.
*
* @deprecated There is no reason to log with fastify. High memory usage and throughput.
* @public
* @static
* @memberof AbstractServer
* @since 3.0.0
* @author Caique Araujo <caique@piggly.com.br>
*/
static defaultLogger(env, root_path, debug) {
const logger = {
file: `${root_path}/logs/server.log`,
level: debug ? 'debug' : 'info',
};
if (env === 'production') {
return logger;
}
return {
...logger,
serializers: {
req: (req) => ({
hostname: req.hostname,
method: req.method,
url: req.url,
}),
res: (res) => ({
statusCode: res.statusCode,
}),
},
transport: {
options: {
colorize: true,
ignore: 'pid',
messageFormat: '{msg} [id={reqId} method={req.method} url={req.url} statusCode={res.statusCode} responseTime={responseTime}ms hostname={req.hostname}]',
translateTime: true,
},
target: 'pino-pretty',
},
};
}
}
//# sourceMappingURL=AbstractServer.js.map