dapr / dapr/js-sdk

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

Open
#538 3 comments 1 reaction 0 assignees View on GitHub
needs-team-attention pinned
Dominant language
JavaScript
Stars
217
Forks
104
PR merge metrics
No merged PRs in 30d

Description

## 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

```javascript
class EventData {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
```

2. Try to send an event with an instance of this class

```javascript
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: {}
```

3. 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:

```javascript
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`)

```javascript
{
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.

4. Extra: Convert `data` before sending the event and check the contents of the event received by Dapr:

```javascript
// ...
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)

```javascript
{
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'
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.