All Projects → pvarentsov → nestjs-pg-notify

pvarentsov / nestjs-pg-notify

Licence: MIT license
NestJS custom transport strategy for PostgreSQL Pub/Sub.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to nestjs-pg-notify

nuxtjs-nestjs-starter
Starter project for nuxtjs and nestjs all in one integrated.
Stars: ✭ 56 (+5.66%)
Mutual labels:  nestjs
nestjs-microservice-boilerplate
Boilerplate for a TCP Microservice in NestJS with TypeORM and tests
Stars: ✭ 45 (-15.09%)
Mutual labels:  nestjs
nestjs-throttler-storage-redis
Redis storage provider for the nestjs-throttler package.
Stars: ✭ 56 (+5.66%)
Mutual labels:  nestjs
unnue-nuxt
开媛笔记,基于nuxt ssr首屏服务器端渲染 ⚡。用于分享、记录、交流和学习,希望可以帮助到小伙伴们。同时网站在永久更新,备好鸡血,一起来战 Ooh aah!
Stars: ✭ 98 (+84.91%)
Mutual labels:  nestjs
BUA-FE
本科毕设,搭建一套小而全面的校园外卖系统。主要使用wei-xin-mini + TypeScript + nest.js + typeORM + rabbitmq技术栈。
Stars: ✭ 20 (-62.26%)
Mutual labels:  nestjs
starter-reactnative-nestjs-mysql
Starter mobile ReactNative NestJS MySQL with continuous integration and AWS deployment
Stars: ✭ 16 (-69.81%)
Mutual labels:  nestjs
mpcast-minapp-uni
播(客)课小程序
Stars: ✭ 14 (-73.58%)
Mutual labels:  nestjs
nestjs-mercurius
NestJs module to use Mercurius as GraphQL server
Stars: ✭ 38 (-28.3%)
Mutual labels:  nestjs
matnbaz
📚 The source-code for matnbaz.net. A monorepo containing the back-end (NestJS/Prisma/Apollo), front-end (Next.js/Apollo) and some tooling.
Stars: ✭ 481 (+807.55%)
Mutual labels:  nestjs
nestjs-dynamoose
Dynamoose module for Nest
Stars: ✭ 84 (+58.49%)
Mutual labels:  nestjs
nestjs-extensions
[WIP] A bunch of useful and opinionated filters, modules, pipes... to use with Nest framework. 😻
Stars: ✭ 43 (-18.87%)
Mutual labels:  nestjs
azure-func-http
Azure Functions HTTP adapter for Nest framework (node.js) 🌥
Stars: ✭ 121 (+128.3%)
Mutual labels:  nestjs
blog-be-next
The back-end platform for Yancey blog.
Stars: ✭ 33 (-37.74%)
Mutual labels:  nestjs
nest-xray
Distributed tracing for Nestjs with AWS X-Ray as the backend. Instrument incoming and outgoing HTTP requests
Stars: ✭ 50 (-5.66%)
Mutual labels:  nestjs
mmo-arch
Base Architecture for creating scalable games using microservices through Angular, Phaser, NestJS, NATS, and MySQL
Stars: ✭ 25 (-52.83%)
Mutual labels:  nestjs
nest-serve
使用 Nestjs 8.x 以微服务方式开发的基础管理后台服务,并搭配 React 开发的管理后台前端(可自行根据 swagger 的接口开发对应的管理后台前端)
Stars: ✭ 97 (+83.02%)
Mutual labels:  nestjs
truthy
Open source headless CMS API written using NestJS, that has pre built modules like User Management, Role Management, Permission Management, Email Module, Account Settings, OTP, Throttling, RBAC support, Localization, and many more.
Stars: ✭ 200 (+277.36%)
Mutual labels:  nestjs
nest-rabbit-tasks
nest-rabbit-worker is a TaskQueue based upon RabbitMQ for NestJS
Stars: ✭ 29 (-45.28%)
Mutual labels:  nestjs
nestjs-rmq
A custom library for NestJS microservice. It allows you to use RabbitMQ or AMQP.
Stars: ✭ 182 (+243.4%)
Mutual labels:  nestjs
crypto-watchdog
Crypto Watchdog is an open-source developer friendly project, periodically queries crypto market and notifies potential pumps & recently added tokens/coins via web-hooks.
Stars: ✭ 22 (-58.49%)
Mutual labels:  nestjs

NestJS PG Notify

NestJS custom transport strategy for PostgreSQL Pub/Sub.

License: MIT NPM Version NPM Downloads CI Status Quality Gate Status Coverage

PostgreSQL async notifications

PostgreSQL can be used as a Pub/Sub message broker. Its functionality is similar to the Redis Pub/Sub, but has its own features and limitations.

The References section contains links that you may find useful to familiarize yourself with the PostgreSQL asynchronous notifications.

Custom transporter

NestJS PG Notify implements Pub/Sub messaging paradigm using PostgreSQL as a NestJS custom transporter. It wraps the pg-listen library under the hood.

It can be used in microservice and hybrid NestJS applications. The example folder contains examples for both types of applications.

Installation

$ npm i nestjs-pg-notify pg

Usage

Setup PgNotifyServer as custom strategy

import { PgNotifyServer } from 'nestjs-pg-notify';

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  strategy: new PgNotifyServer({
    /**
     * Required parameter
     * Corresponds to the "pg" library's connection config
     */  
    connection: {
      host: 'localhost',
      port: 5432,
      database: 'pgnotify',
      user: 'pgnotify',
      password: 'pgnotify',
    },
    /**
     * Optional parameter
     * Contains retry-strategy config passing the data to the "pg-listen" library
     */
    strategy: {
      retryInterval: 1_000,
      retryTimeout: Infinity,
    },
    /**
     * Optional parameter
     * Overrides default logger
     */
    logger: new Logger(),
  })
});

Bind message handlers

NestJS PG Notify offers two decorators to register message handlers: @PgNotifyEventPattern() and @PgNotifyMessagePattern(). These are an alternative to standard decorators: @EventPattern() and @MessagePattern().

Message handler's binding can be used only within controller classes.

import { PgNotifyContext, PgNotifyEventPattern, PgNotifyMessagePattern } from 'nestjs-pg-notify';

@Controller()
export class AppController {

  @PgNotifyEventPattern({event: 'greeting'})
  @UsePipes(new ValidationPipe())
  onGreetingEvent(@Payload() payload: any, @Ctx() context: PgNotifyContext): void {
    Logger.log(payload.message);
  }

  @PgNotifyMessagePattern('greeting')
  @UsePipes(new ValidationPipe())
  onGreetingRequest(@Payload() payload: any, @Ctx() context: PgNotifyContext): string {
    Logger.log(payload.message);
    return 'Hello!';
  }

}

The standard decorator @Ctx() allows access to the context of the incoming request. In our case, the context object is an instance of PgNotifyContext.

Setup PgNotifyClient as client proxy

The client proxy can be registered as a custom provider. The configuration is the same as the configuration of the PgNotifyServer.

import { PgNotifyClient } from 'nestjs-pg-notify';

@Module({
  providers: [
    {
      provide: 'PG_NOTIFY_CLIENT',
      useFactory: (): ClientProxy => new PgNotifyClient({
        connection: {
          host: 'localhost',
          port: 5432,
          database: 'pgnotify',
          user: 'pgnotify',
          password: 'pgnotify',
        },
        strategy: {
          retryInterval: 1_000,
          retryTimeout: Infinity,
        }, 
      })
    },
  ],
  exports: [
    'PG_NOTIFY_CLIENT',
  ]
})
export class AppModule {}

Then we can inject the client proxy.

import { PgNotifyResponse } from 'nestjs-pg-notify';

export class AppService {
  constructor(
    @Inject('PG_NOTIFY_CLIENT')
    private readonly client: ClientProxy,
  ) {}
   
  sendRequest(): Observable<PgNotifyResponse> {
    // Send request and expect response
    return this.client.send('greeting', {message: 'Hello!'}).pipe(
      timeout(2_000),
      tap(response => Logger.debug(response)),
    );
  }
  
  emitEvent(): Observable<void> {
    // Emit event
    return this.client.emit({event: 'greeting'}, {message: 'Hello!'});
  }
}

Exception filters

The client proxy generates request identifier when we send requests using client.send(). The request identifier in the context of the incoming request means that we need to prepare an error response for the client.

We can use the PgNotifyResponse.error() factory in order to unify the structure of the response.

import { PgNotifyContext, PgNotifyResponse } from 'nestjs-pg-notify';

@Catch()
export class ExceptionFilter implements ExceptionFilter {
  catch(error: Error, host: ArgumentsHost): Observable<PgNotifyResponse|void> {
    const {status, message} = parseError(error);
    const context = host.switchToRpc().getContext<PgNotifyContext>();
    const requestId = context.getRequestId();

    Logger.error(message, error.stack, 'PgNotifyExceptionFilter');

    if (requestId) {
      return of(PgNotifyResponse.error(message, status));
    }

    return of(undefined);
  }
}

Then we can register the filter using the standard @UseFilters() decorator. It supports method-scope and controller-scope modes.

@Controller()
@UseFilters(ExceptionFilter)
export class AppController {
  // ...
}

Interceptors

import { PgNotifyContext } from 'nestjs-pg-notify';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  public intercept(context: ExecutionContext, next: CallHandler): Observable<void> {
    const pgNotifyContext = context
      .switchToRpc()
      .getContext<PgNotifyContext>();

    return next.handle().pipe(
      tap(() => Logger.log(JSON.stringify(pgNotifyContext), LoggingInterceptor.name)),
    );
  }
}

To register interceptor we can use @UseInterceptors() decorator. It also supports method-scope and controller-scope modes.

@Controller()
@UseInterceptors(LoggingInterceptor)
export class AppController {
  // ...
}

API

API documentation is available here.

References

  1. PostgreSQL Documentation:
  2. PgBouncer Documentation:
  3. NestJS Documentation:
  4. Dependencies:

License

This project is licensed under the MIT License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].