0.0.3 • Published 1 year ago

@platohq/nestjs-google-pubsub v0.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

@platohq/nestjs-google-pubsub

The NestJS module based on the official Google PubSub package

How to install

npm install @platohq/nestjs-google-pubsub

or

yarn add @platohq/nestjs-google-pubsub

How to use

You can use this package to integrate Google PubSub with NestJS for both producing or consuming messages.

Producing messages

To add the ability to publish message to a given Google PubSub topic to any module, you need to do the following:

Step 1. Import the ClientsModule

NestJS allows us to abstract the integration with a message broker pretty easily. To do that, you just need to import the ClientsModule to your module, like this:

import { Module } from '@nestjs/common';
import { ClientsModule } from '@nestjs/microservices'; // <-- Import statement
import { GooglePubSubClient } from '@platohq/nestjs-google-pubsub'; // <-- Import statement

@Module({
  imports: [{
    ClientsModule.register([{
      customClass: GooglePubSubClient,
      options: {
        projectId: 'your-project-id',
        // ... other options
        // You can check the list of available options on "Options" section of this document
      }
    }])
  }], // <-- Module metadata
  // ... everything else
})
export class YourModule {}

You can check a list with all available options on the Options section. Also, you can configure the GooglePubSubClient async using a dynamic configuration, like any other NestJS module.

Step 2. Inject the Google PubSub client to your service

With the ClientsModule declared as a depedency, you can inject the GooglePubSubClient to your service, like the following:

import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices'; // <-- ClientProxy interface
import { GooglePubSubClient } from '@platohq/nestjs-google-pubsub'; // <-- Injection token

@Injectable()
export class YourService {
  constructor(
    @Inject(GooglePubSubClient) // <-- Injection decorator
    private readonly client: ClientProxy, // <-- ClientProxy instance
  ) {
  }
  // ... everything else
}

With that in place, you can now use the client property to publish messages to a given topic.

Step 3. Publish new messages

Right now we can only emit events (messages without response) to our topics, so to publish a message to a topic named test-topic, you should do the following:

import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { GooglePubSubClient } from '@platohq/nestjs-google-pubsub'; // <-- Injection token

@Injectable()
export class YourService {
  constructor(
    @Inject(GooglePubSubClient)
    private readonly client: ClientProxy,
  ) {
  }
  public myCoolFunction(): void {
    this.client.emit('test-topic', "A clever message"); // <-- Emitting a message
  }
  // ... everything else
}

This will publish a message on topic named test-topic containing the following payload:

{
  "data": "A clever message"
}

It is important to notice that everything passed as the second argument for the emit function will be serialized inside a key named data. So, if your payload is an object, that object will be inside a key named data as well.

Consuming messages

Creating a new consumer within this package is pretty straightforward. To do it, follow these steps:

Step 1. Creates a new microservice

In your main.ts (or similar) file, add the following code to create a new NestJS Microservice:

import {NestFactory} from "@nestjs/core";
import {GooglePubSubTransportStrategy} from "@platohq/nestjs-google-pubsub";

const app = await NestFactory.create(AppModule);

app.connectMicroservice({
  strategy: new GooglePubSubTransportStrategy({
    projectId: 'your-project-id',
    appName: 'your-app-name',
  }),
});
await app.startAllMicroservices();

Step 2. Decorate your entrypoint

The first step is using the EventPattern decorator to define the topic you want to listen. Since our current integration with Google Cloud PubSub only enables emitting events (without waiting for responses) you should always use the EventPattern decorator, like the following:

import { Controller } from '@nestjs/common';
import { EventPattern } from '@nestjs/microservices'; // <-- Imports the decorator
import { GooglePubSubContext, SerializedMessage } from '@platohq/nestjs-google-pubsub'; // <-- Imports the context

@Controller()
export class MyController {
  @EventPattern('test-topic') // <-- Attached to the event listener
  public myConsumer(msg: SerializedMessage<unknown>, ctx: GooglePubSubContext): void {
    // ... your logic
  }

  // ... everything else
}

As you can imagine, with that decorator any incoming message on test-topic will be delivered to the myConsumer method. Also, you can pass an optional argument to the SerializedMessage to increase type safety.

Finally, there is an optional second argument ctx which contains all the data provided by Google PubSub regarding that method.

Options

You can use the available options to customize how both your producer and consumer works. You can check the available options below.

OPTIONREQUIREDTYPEDEFAULTDESCRIPTION
projectIdYesnullstringThe Google Cloud project ID
autoCreateTopicsNobooleantrueWhether to create topics if they don't exist
autoCreateSubscriptionsNobooleantrueWhether to create subscriptions if they don't exist
autoAckNobooleantrueWhether to automatically acknowledge messages
appNameNostringnestjsThe name of the application
signatureMarkerNostring__The marker to separate the app name as a prefix on subscriptions
serializerNoSerializerSerializerThe serializer to use to serialize new messages that we're sending
deserializerNoDeserializerDeserializerThe deserializer to use to deserialize messages that we're receiving

Known limitations

  • We currently only support emitting events (without a response). So, we still need to implement the request/reply.