dapr / dotnet-sdk

Dapr SDK for .NET
Apache License 2.0
1.11k stars 336 forks source link

Expose a way to pass a self-built CloudEvent to DaprClient #1328

Open andyfurniss4 opened 3 months ago

andyfurniss4 commented 3 months ago

Describe the feature

Curently, we have the ability to pass a payload, or a payload and a dictionary of metadata. When using Dapr PubSub with CloudEvents (the default), this all gets wrapped up in a CloudEvent behind the scenes.

public abstract Task PublishEventAsync<TData>(string pubsubName, string topicName, TData data, CancellationToken cancellationToken = default);
public abstract Task PublishEventAsync<TData>(string pubsubName, string topicName, TData data, Dictionary<string, string>  metadata, CancellationToken cancellationToken = default);

I am trying to create a way to enforce the format of the CloudEvent type field value. Having to pass this as a item in the metadata dictionary every time I want to poublish an event leads to a lot of duplication and leaves it open to human error since the string will be manually written by a developer each time an event needs to be published. Ideally, I'd be able to wrap up this logic into our own CloudEvent factory or something similar and then pass the resulting CloudEvent to Dapr.

There doesn't seem to be a nice way around this without creating an event-publishing abstraction layer around Dapr (which feels a bit ridiculous since Dapr is an abstraction itself). The DaprClient is abstract, but I'm pretty sure this is just to facilitate mocking since there is a huge amount of stuff in there that would need implementing if we were to try to extend this class with a new method. The DaprClientGrpc class is also internal so we can inherit from this either.

It would be great if there was a way to pass a self-built CloudEvent to the DaprClient, whilst retaining the benefits of having CloudEvents turned on in the Dapr configuration

image

Release Note

RELEASE NOTE: ADD Ability to pass a self-built CloudEvent to DaprClient PubSub method.

philliphoff commented 3 months ago

@andyfurniss4 It looks like CloudEvent<TData> automatically sets its type as application/json while the base CloudEvent type allows setting any type. If you're not using JSON, can you create your own derived CloudEvent type that sets the type to your specific type? Then you shouldn't need to set the metadata directly.