Skip to content

Dapr client.pubsub.publish Function Does Not Send CloudEvent with Correct Data Field Content #538

@MotaOcimar

Description

@MotaOcimar

Expected Behavior

When calling the client.pubsub.publish function for a class, Dapr should send a CloudEvent with the data field filled with the value passed to the function. A type conversion could be done so that the value is sent correctly. For example, JavaScript's Object.assign could be used.

If this option is not possible, the Dapr sdk function should return a response with the error field filled with a message describing the error.

Actual Behavior

When calling the client.pubsub.publish function for a class, Dapr sends a CloudEvent with the data field empty. The data_base64 field is filled with the value [object Object], which does not describe the real object that should be sent.

Steps to Reproduce the Problem

  1. Create a class with the data you want to be sent by Dapr
class EventData {
    constructor(id, name) {
        this.id = id;
        this.name = name;
    }
}
  1. Try to send an event with an instance of this class
const client = new DaprClient({daprHost, daprPort});
const data = new EventData(1, 'Teste');
const response = await client.pubsub.publish("pubsub", "topic", data);
console.log("Response: ", response); // Response:  {}
  1. Check the contents of the event received by Dapr. One possibility is to use a Dapr subscriber receiving the events in JSON format instead of CloudEvent:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;

app.use(bodyParser.json({ type: 'application/*+json' }));

// Subscribe to topic
app.get('/dapr/subscribe', (_req, res) => {
    res.json([ { pubsubname: "pubsub", topic: "topic", route: "route" } ]);
});

// Handle incoming events
app.post('/route', (req, res) => {
    console.log(req.body);
    res.sendStatus(200);
});

app.listen(port, () => console.log(`Node App listening on port ${port}!`));

The received event will be something like:
(Note there is no data field, but data_base64)

{
  data_base64: 'W29iamVjdCBPYmplY3Rd',
  datacontenttype: 'application/octet-stream',
  id: '951b5617-4929-413b-aebe-f092044d0eaf',
  pubsubname: 'pubsub',
  source: 'subscriber',
  specversion: '1.0',
  time: '2023-10-18T13:39:41-03:00',
  topic: 'topic',
  traceid: '00-8431b0187017d5f21cf078b68061a55e-eed8a8f906f35146-01',
  traceparent: '00-8431b0187017d5f21cf078b68061a55e-eed8a8f906f35146-01',
  tracestate: '',
  type: 'com.dapr.event.sent'
}

Decoding the value of data_base64 using base64, the value will be literally [object Object], which does not describe the real object that should have been sent.

  1. Extra: Convert data before sending the event and check the contents of the event received by Dapr:
// ...
const response = await client.pubsub.publish(pubSubId, topic, Object.assign({}, data));
// Object.assign was used to convert the type                 ^^^^^^^^^^^^^^^^^^^^^^^
console.log("Response: ", response); // Response:  {}

The received event will be something like:
(Note that the data field is filled correctly)

{
  data: { id: 1, name: 'Teste' },
  datacontenttype: 'application/json',
  id: 'deb2b6fe-2727-4ae9-8190-4027b8911d60',
  pubsubname: 'pubsub',
  source: 'subscriber',
  specversion: '1.0',
  time: '2023-10-18T13:45:58-03:00',
  topic: 'topic',
  traceid: '00-b29556072612451e044b137c8ed741ee-fb12d350adf79fa2-01',
  traceparent: '00-b29556072612451e044b137c8ed741ee-fb12d350adf79fa2-01',
  tracestate: '',
  type: 'com.dapr.event.sent'
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions