@webundsoehne/nestjs-util
v7.1.9
Published
NestJS skeleton util library
Downloads
2,173
Readme
@webundsoehne/nestjs-util
Description
This is a collection of useful modules for creating a NestJS project. Mostly all of these modules are used by the in-house boilerplate of Web & Söhne.
Modules
Decorators
Retry Decorator
Wrap a class method with this decorator to retry it couple of more times. Useful for external service dependent tasks.
@Timeout(MigrationTask.name, 0)
@Retry({
name: MigrationTask.name,
retry: 24,
interval: 3 * 1000
})
async migrate(): Promise<void> {
try {
await this.connection.runMigrations({ transaction: 'all' })
} catch (error) {
this.logger.error(error.message)
throw error
}
}
UseMaintenanceLocker Decorator
Whenever the given class method fires, it will also activate the maintenance mode through MaintenanceModule
. For this MaintenanceModule
should be injected in to the context of the given module.
@Timeout(MigrationTask.name, 0)
@UseMaintenanceLocker(MigrationTask.name)
async migrate(): Promise<void> {
try {
await this.connection.runMigrations({ transaction: 'all' })
} catch (error) {
this.logger.error(error.message)
throw error
}
}
Filters
We implemented a generic ExceptionFilter
called GlobalExceptionFilter
, which catches all errors and sets the payload to a userfriendly information. The real exception and stacktrace will be just logged in debug
logger mode.
Usage
import { GlobalExceptionFilter } from '@webundsoehne/nestjs-util'
@Module({
providers: [
{
provide: APP_FILTER,
useClass: GlobalExceptionFilter
}
]
})
class ServerModule implements NestModule {}
Reporting to sentry.io
GlobalSentryExceptionFilter
extends the functionality of the GlobalExceptionFilter
with additional reporting of errors to sentry.io. The options for sentry need to be set in the config file. At least the dsn
has to be defined for a successful initialization. If the initialization was not successful, a warning will be displayed and the filter behaves as the base GlobalExceptionFilter
. By default, only unhandled or critical exceptions with HTTP statuscode >= 500 will be reported. Setting the optional config param reportAll
to true will report all exceptions to sentry e.g. HttpExceptions, AuthorizationExceptions etc.
This filter requires the @sentry/node
package to be installed in your project. Please add it to your package.json
dependencies.
Example sentry config
sentry:
dsn: https://[email protected]/12312345
environment: appname_production
reportAll: false
Http
The HttpExceptionFilter
extends from the GlobalExceptionFilter
and just catches all HttpException
errors. It just overwrites the protected payload()
method, which builds the message for the user.
Usage
import { HttpExceptionFilter, GlobalExceptionFilter } from '@webundsoehne/nestjs-util'
@Module({
providers: [
{
provide: APP_FILTER,
useClass: GlobalExceptionFilter
},
{
provide: APP_FILTER,
useClass: HttpExceptionFilter
}
]
})
class ServerModule implements NestModule {}
Bad-Request
The BadRequestExceptionFilter
extends from the GlobalExceptionFilter
and just catches BadRequestException
errors. This will handle the complex validation error messages (ValidationError
) in the overwritten payload()
method, which just happens on BadRequestException
errors.
We don't handle them in the normal HttpExceptionFilter
because of performance reasons.
Usage
I hope you recognized that the order of the exception filters is relevant and required.
import { BadRequestExceptionFilter, HttpExceptionFilter, GlobalExceptionFilter } from '@webundsoehne/nestjs-util'
@Module({
providers: [
{
provide: APP_FILTER,
useClass: GlobalExceptionFilter
},
{
provide: APP_FILTER,
useClass: HttpExceptionFilter
},
{
provide: APP_FILTER,
useClass: BadRequestExceptionFilter
}
]
})
class ServerModule implements NestModule {}
Middleware
The middleware of the maintenance module uses directly the MaintenanceService
to check if there exists a lock file and raises the correct exception. You will see the implementation in the usage block above.
Info-Header
The information header middleware is a really short NestMiddleware
which set the X-Api-Name
and X-Api-Version
response header out of the process.env
data. Both environment variables will be set with the setEnvironmentVariables
util function, which loads the information from the package.json
.
Usage
import { SetApiInfoHeaderMiddleware, setEnvironmentVariables } from '@webundsoehne/nestjs-util'
class ServerModule implements NestModule {
async configure(consumer: MiddlewareConsumer): Promise<any> {
await setEnvironmentVariables()
consumer.apply(SetApiInfoHeaderMiddleware).forRoutes({ path: '*', method: RequestMethod.ALL })
}
}
Modules
Maintenance
The maintenance module gives you the possibility to generate and remove a lock file, as well as checking if the lock file exists and throwing a preconfigured ServiceUnavailableException
error. You may use the maintenance module anywhere in your project, e.g. for database migrations.
Usage
import { MaintenanceMiddleware, MaintenanceModule } from '@webundsoehne/nestjs-util'
@Module({
imports: [MaintenanceModule]
})
class ServerModule implements NestModule {
async configure(consumer: MiddlewareConsumer): Promise<any> {
consumer.apply(MaintenanceMiddleware).forRoutes({ path: '*', method: RequestMethod.ALL })
}
}
Methods
| Name | Return | Description | | -------------- | ------- | ------------------------------------- | | enable | void | Create the configured lock file | | disable | void | Remove the generated lock file | | isEnabled | Boolean | Check if there is already a lock file | | throwException | void | Throw the preconfigured exception |
Configuration
If there is no
misc.maintenanceNotification
set, it will be generated with following template string: `${url.basePath} is currently down for maintenance`
| Key | Type | Default | Description | | ---------------------------- | ------ | ------------------ | ------------------------------------------------------------- | | url.basePath | String | | The base API url of your project | | misc.maintenanceNotification | String | (see hint above) | The notification, which will be thrown in case of maintenance | | misc.lockfile | String | 'maintenance.lock' | The filepath of the projects's maintenance lock file |
Providers
Config
This is a NestJS service which allows you to use the great config library with decorators. For scripts or in common no classes, you can use it normally too.
Important
The
@Configurable()
has to be the last decorator before the function is initiated.
Usage
import { ConfigParam, ConfigService, Configurable, InjectConfig } from '@webundsoehne/nestjs-util'
// 1. the old (static) way
const configValue1 = ConfigService.get('value')
class CustomService {
// 2. inject the whole config service, normally you wont use this ways
constructor ( @InjectConfig() private readonly config: ConfigService) {
const configValue2 = this.config.get('value')
}
// 3. load the config directly as function parameter
@AnythingElse()
@Configurable()
testConfig (@ConfigParam('value', 'default-value') value3?: string) {
...
}
}
Logger
Customized logger service, which uses winston for nicer output.
Usage
Set an instance of the logger to the application during creation as part of the NestApplicationOptions
.
import { LoggerService } from '@webundsoehne/nestjs-util'
const app = await NestFactory.create<INestApplication>(ServerModule, new FastifyAdapter(), {
logger: new LoggerService()
})
After the logger got set to the application, all NestJS logging output will be handled by our customized logger.
import { Logger } from '@nestjs/common'
class CustomService {
private readonly logger: Logger = new Logger(this.constructor.name)
private readonly loggerWithoutContext: Logger = new Logger()
constructor() {
this.logger.verbose('log message')
// [2020-01-01T12:00:00.000Z] [verbose] [CustomService] - log message
this.logger.verbose('log message, with custom context', 'ForcedContext')
// [2020-01-01T12:00:00.000Z] [verbose] [ForcedContext] - log message, with custom context
this.logger.loggerWithoutContext('log message')
// [2020-01-01T12:00:00.000Z] [verbose] [LoggerService] - log message
this.logger.loggerWithoutContext('log message, with custom context', 'ForcedContext')
// [2020-01-01T12:00:00.000Z] [verbose] [ForcedContext] - log message, with custom context
}
}
Pipes
Extended pipes provide capabilities over the default ones for better interacting with this library.
Validation Pipe
This validation pipe extends the default pipe for class-validator
while it also provides a way to override the settings for a given path utilizing the accompanying decorator.
Usage
This can either be used with a useClass
or to extend the options useFactory
. The default ValidationPipeOptions
are { whitelist: true }
.
import { Module } from '@nestjs/common'
import { APP_PIPE } from '@nestjs/core'
import { ExtendedValidationPipe } from '@webundsoehne/nestjs-util'
@Module({
providers: [
{
provide: APP_PIPE,
useClass: ExtendedValidationPipe
}
]
})
export class ServerModule {}
Stay in touch
- Author: Backend Team
- Website: Web & Söhne