nest icon indicating copy to clipboard operation
nest copied to clipboard

[microservices] Ability to send non-json mqtt payloads

Open afaure-bkk opened this issue 4 years ago • 8 comments

Feature Request

Is your feature request related to a problem? Please describe.

Working in IOT context, I have come across cases where I want to be able to send MQTT messages in a raw format. My device is expecting an unquoted string as an input: ON or OFF. It does not understand a json payload: "ON" or "OFF" are not valid message payloads. The (great, really helped me get started :) ) article by @johnbiundo (Part 3: Techniques for Application Integration with NestJS and NATS) did not allow me to solve this issue, since the mqtt client code seems to always stringify the payload produced by my custom serializer (see https://github.com/nestjs/nest/blob/baadb3f92593da397952060ec868bb27b9c766bf/packages/microservices/client/client-mqtt.ts#L161)

Describe the solution you'd like

I would like a way to override the call to JSON.stringify somehow, and send the raw result from my serializer as the final payload for the event

Perhaps there could be an option when declaring a serializer for the MQTT client to activate a 'raw' mode, where Nest would take whatever the output of the serializer and send it:

  protected dispatchEvent(packet: ReadPacket): Promise<any> {
    const pattern = this.normalizePattern(packet.pattern);
    let serializedPacket = this.serializer.serialize(packet);
    if (!this.options.rawEventPayload) {
        serializedPacket = JSON.stringify(serializedPacket);
    }
    return new Promise((resolve, reject) =>
      this.mqttClient.publish(pattern, serializedPacket, err =>
        err ? reject(err) : resolve(),
      ),
    );
  }

(pardon my typescript, this is mostly for explanation purpose)

Teachability, Documentation, Adoption, Migration Strategy

The option would be inactive by default, no impact on existing nest based projects, no migration

What is the motivation / use case for changing the behavior?

Not every mqtt subscriber accepts json data, I wish the ability to send messages to such subscribers natively in nestjs

afaure-bkk avatar May 19 '20 17:05 afaure-bkk

How to support this issue? Im works in IOT context and really need this feature too. Now i resolve it problem with create a native connection for publishing messages.

singlesly avatar Jun 11 '20 13:06 singlesly

Imho it would make even more sense to remove stringify in this part altogether (and set JSON.stringify as the default serializer) - what is the point of a serializer if the output will be serialized again. But as this would be a breaking change a raw option would do just fine 👍

chartinger avatar Jul 06 '20 18:07 chartinger

All the Nest.js module expect packet to be JSON format. Kafka and RabitMQ module have similar stringify or parse command. These corrupt the packet. Nest.js should remove or provide way to override JSON.stringify() and JSON.parse() methods baked in the framework

devendraap avatar Dec 24 '20 15:12 devendraap

I can't use nestJS without this feature. I have existing topics in my broker that are processed by different languages and frameworks.

mknj avatar May 18 '21 12:05 mknj

@kamilmysliwiec (or whomever might have authority on this one), It looks like the solution here might be to modify the default IdentitySerializer to return the stringified packet and remove JSON.stringify from the dispatchEvent. This might still be a breaking change for anyone expecting their packet to be stringified after running through a custom serializer. However, the usefulness of custom serializers are limited since the packet is then stringified afterwards. Probably a valid breaking change for the next major version bump? I'm willing to work on a PR for this if a decision is made on the direction.

YeomansIII avatar Jan 14 '22 13:01 YeomansIII

Sounds good @YeomansIII! Contributions are more than welcome :)

kamilmysliwiec avatar Jan 14 '22 14:01 kamilmysliwiec

will it be solved here? #8972 Is something missing, how can i help? :)

Clex1o1 avatar Apr 21 '22 11:04 Clex1o1

Hi, I'm relatively new to Nestjs and would need this new feature so bad.

What's the actual alternative to this?, create a custom ClientProxy?

For the moment I've created a custom client proxy, extending ClientMqtt, and overriden the publish method, with none of the packet serialization code.

That way I can publish sending raw text data to broker.

ramirezsandin avatar Sep 25 '22 09:09 ramirezsandin