0.0.4-beta.3 • Published 2 years ago

gleycerparra-nestjs-utils v0.0.4-beta.3

Weekly downloads
-
License
UNLICENSED
Repository
gitlab
Last release
2 years ago

Carrier HD Utils

Installation

Create a .npmrc file with the following content:

@falabella-gitlab:registry=https://gitlab.falabella.com/api/v4/projects/54431/packages/npm/
//gitlab.falabella.com/api/v4/projects/54431/packages/npm/:_authToken=AUTH_TOKEN_FROM_GITLAB

then you can execute npm install @falabella-gitlab/nestjs-utils.

Overview

This project is a NPM package made to contain utilities functions to be reused within the Carrier HD ecosystem.

Currently you can find out the following utilities:

Usage

Google Pub/Sub (GCPPubSub3PL)

For a deep introduction to Google Pub/Sub please refer to the official documentation:

To configure Google Pub/Sub is suggested to export an environment variable with your credentials:

On Mac/Linux:

export GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"

On Windows:

For Powershell:

$env:GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"

For Command Prompt:

set GOOGLE_APPLICATION_CREDENTIALS=KEY_PATH

To use GCPPubSub3PL which is the integration for Google Pub/Sub, get the instance as follow:

this.pubSubInstance = GCPPubSub3PL.getInstance();

GCPPubSub3PL is an static method which refer to a singleton instance, a method init is also available to configure credentials if you want to configure Google Pub/Sub from the code implementation instead of through environment variables, e.g:

this.pubSubInstance = GCPPubSub3PL.init(YOUR_CREDENTIALS);

To emit a message to a topic, in a NestJs project you can create a service or service method, e.g:

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { GCPPubSub3PL } from 'carrier-hd-utils';

@Injectable()
export class MessageEmmiter {
    private pubSubInstance: GCPPubSub3PL;
    private processedTopicName: string;

    constructor(
        private config: ConfigService
    ) {
        // get singleton instance
        this.pubSubInstance = GCPPubSub3PL.getInstance();

        // getting topic name from env variables
        this.processedTopicName = this.config.get("TOPIC_NAME");

    }

    // emitting a message to already configured topic
    public async emitShipmentProcessed(data) {
        const messageId =
            await this.pubSubInstance.emit(this.processedTopicName, data);
        return { data, messageId };
    }
}

Google Pub/Sub has two types of suscription as is detailed in this documentation. The pull strategy is also covered by this utility.

To subscribe to a topic, in a Nestjs project you can create a service or service method, e.g:

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { GCPPubSub3PL, SubscriptionHandled } from 'carrier-hd-utils';

const testSchema = {
    title: 'title',
    type: 'object',
    required: ['firstName'],
    properties: {
        "firstName": {
            "type": "string",
            "description": "The person's first name."
        }
    }
};

@Injectable()
export class SubcriptionHandlerService {
    private pubSubInstance: GCPPubSub3PL;

    constructor(
        private config: ConfigService
    ) {

        // get singleton
        this.pubSubInstance = GCPPubSub3PL.getInstance();

        // getting subs name from env variables and subscribe to it [PULL method]
        const validatedSubName = this.config.get("SUBSCRIPTION_NAME");
        this.pubSubInstance.Subscription3PLPubSub(
            validatedSubName, // suscription name
            (m) => this.shipmentValidatedSubscriber(m), // handler
            { validationSchema: testSchema } // option [validation]
        );

    }

    // messages are receiving here
    public async shipmentValidatedSubscriber(data): Promise<SubscriptionHandled>{
        // your logic

        return { ack: true }
    }
}

As you can notice you should implement a handler method and pass it to javascript Subscription3PLPubSub method in order to handle the received messages. You must return an object with { ack: boolean } to send and acknowledgment of the received message.

3PL Logger

In main.ts file add the following configuration

import { ctxHeaderReqIdOnSend, withContext, withRequestId } from '3pl-logger';

async function bootstrap() {

  const app =
    await NestFactory.create<NestFastifyApplication>(AppModule,
        new FastifyAdapter({ logger: false })); // turn off the default fastify logger

  app.use(withContext); // sets the context in every single request
  app.use(withRequestId); // find/create the request id for every request
  app.register(ctxHeaderReqIdOnSend); // include request id header in every response
  ...

In the proyect you can import the get3PLogger method to emit a log

...
import { get3PLogger } from '3pl-logger';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService
  ) { }

  private logger = get3PLogger(AppController.name);

  @Post()
  async getHello(@Body() data: any): Promise<ServiceResponse<any>> {

    this.logger.info('FROM controller', { methodName: 'Post getHello' });

    return this.appService.publish(data);
  }

  ...

The logger object has 3 methods; info, debug, error. Each one has 2 arguments. First one can be a string or object (LoggerData interface) and the second its optional (LoggerMetaData interface)

this.logger[info debug error](data: LoggerData | string, meta?: LoggerMetaData)

export interface LoggerData {
    message: string;
    reqId?: string;
    [key: string]: any;
}
export interface LoggerMetaData {
    methodName?: string,
    functionName?: string,
    className?: string,
    filePath?: string,
    status?: string
}