Table of Contents

Class ApiClient

Namespace
Virtufin.Api.Client
Assembly
Virtufin.Api.Client.dll

Client for the Virtufin API Gateway: dynamic per-service RPC dispatch (service names as dynamic members, e.g. client.workmanager.SomeMethod()), plus direct methods for state, pub/sub, triggers and config.

public class ApiClient : DynamicObject, IDynamicMetaObjectProvider, IDisposable
Inheritance
ApiClient
Implements
Inherited Members

Examples

using var client = new ApiClient();
var workers = await client.workmanager.ListWorkers();
// Equivalent to:
var workers = await client.InvokeAsync("workmanager", "ListWorkers");

Remarks

Before 0.7.0 this was two classes: a narrow ApiClient (host/port only, no TLS or API key) whose .Gateway property returned the real, full-featured GatewayClient. They are merged here — one class, matching this SDK's Python and TypeScript counterparts more closely than either the two-class or the auth-less shape did alone. .Gateway is kept, returning this, purely so existing client.Gateway.<service>.<Method>(...) call sites keep compiling.

client.workmanager triggers TryGetMember(GetMemberBinder, out object?), which creates or returns a cached ServiceClient for "workmanager". service.ListWorkers() triggers TryGetMember(GetMemberBinder, out object?), which returns a callable that invokes via the Gateway's InvokeJson RPC.

Constructors

ApiClient(GrpcChannel)

Creates a new ApiClient from a pre-built gRPC channel -- the escape hatch for anything the host/port/tls/apiKey constructor can't express (a custom Interceptor, a non-default HttpMessageHandler, etc.). Host and HttpPort are not meaningful from a raw channel and are left at their defaults ("localhost", 0).

public ApiClient(GrpcChannel channel)

Parameters

channel GrpcChannel

The gRPC channel to use for communication.

ApiClient(string, int?, bool, string?)

Creates a new ApiClient.

public ApiClient(string host = "localhost", int? grpcPort = null, bool tls = false, string? apiKey = null)

Parameters

host string

The host address (default: "localhost").

grpcPort int?

The gRPC port (default: DefaultGrpcPort). Previously named httpPort and, when omitted, defaulted to DefaultHttpPort -- the wrong constant for a channel this class only ever builds as gRPC. No known caller relied on the default (every one passes a port explicitly), but fixed here regardless.

tls bool

Use an HTTPS channel, verified against system CA roots.

apiKey string

Sent as x-api-key on every call, via a default header on the channel's underlying HttpClient. Null sends no key.

Properties

Gateway

Returns this same client. Kept only so client.Gateway.<service>.<Method>(...) -- the pattern used throughout this org's C# workers and examples before 0.7.0 -- keeps compiling unmodified. New code should call directly on the client, e.g. client.workmanager.ListWorkers() instead of client.Gateway.workmanager.ListWorkers().

[Obsolete("ApiClient now exposes gateway methods directly; this property is kept only for source compatibility.")]
public ApiClient Gateway { get; }

Property Value

ApiClient

Host

The host address of the gateway.

public string Host { get; }

Property Value

string

HttpPort

The gRPC port of the gateway.

public int HttpPort { get; }

Property Value

int

Methods

Close()

Closes the client synchronously.

public void Close()

CloseAsync()

Closes the client asynchronously.

public Task CloseAsync()

Returns

Task

DeleteBulkStateAsync(string, IEnumerable<string>, bool, ChangeNotification?, CancellationToken)

Deletes multiple state entries for a service.

public Task<DeleteBulkStateResponse> DeleteBulkStateAsync(string service, IEnumerable<string> keys, bool publishChange = false, ChangeNotification? change = null, CancellationToken cancellationToken = default)

Parameters

service string
keys IEnumerable<string>
publishChange bool

If true, a single state.change event is published for the whole bulk. Default false.

change ChangeNotification

Optional. See SaveStateAsync(string, string, string, string?, bool, bool, ChangeNotification?, CancellationToken) for what this selects.

cancellationToken CancellationToken

Returns

Task<DeleteBulkStateResponse>

DeleteStateAsync(string, string, bool, bool, ChangeNotification?, CancellationToken)

Deletes a state entry and broadcasts a delete event to subscribers asynchronously.

public Task<DeleteStateResponse> DeleteStateAsync(string service, string key, bool publishChange = false, bool includeValue = false, ChangeNotification? change = null, CancellationToken cancellationToken = default)

Parameters

service string

The service name.

key string

The state key.

publishChange bool

If true, a state.change event is published. Default false.

includeValue bool

If true, the last value is included in the state change event payload. Only relevant when publishChange=true.

change ChangeNotification

Optional. See SaveStateAsync(string, string, string, string?, bool, bool, ChangeNotification?, CancellationToken) for what this selects.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<DeleteStateResponse>

DeleteStateResponse with success status.

DeleteTriggerAsync(string, CancellationToken)

Deletes a scheduled trigger.

public Task<DeleteTriggerResponse> DeleteTriggerAsync(string name, CancellationToken cancellationToken = default)

Parameters

name string
cancellationToken CancellationToken

Returns

Task<DeleteTriggerResponse>

Dispose()

Disposes of the client resources.

public void Dispose()

DisposeAsync()

Disposes of the client resources asynchronously.

public ValueTask DisposeAsync()

Returns

ValueTask

GetBulkStateAsync(string, IEnumerable<string>, CancellationToken)

Gets multiple state values for a service and list of keys.

public Task<List<StateItemDto>> GetBulkStateAsync(string service, IEnumerable<string> keys, CancellationToken cancellationToken = default)

Parameters

service string
keys IEnumerable<string>
cancellationToken CancellationToken

Returns

Task<List<StateItemDto>>

GetConfigServiceAsync(string, CancellationToken)

Gets one service's configuration. Throws RpcException with NotFound if the name is not registered.

public Task<GetConfigServiceResponse> GetConfigServiceAsync(string name, CancellationToken cancellationToken = default)

Parameters

name string
cancellationToken CancellationToken

Returns

Task<GetConfigServiceResponse>

GetService(string)

Gets a client for a specific service.

public ServiceClient GetService(string name)

Parameters

name string

The service name.

Returns

ServiceClient

A ServiceClient for the service.

Remarks

ServiceClients are cached internally. Calling this method multiple times with the same service name returns the same cached instance.

GetStateAsync(string, string, CancellationToken)

Gets a single state value asynchronously by service and key.

public Task<(string Value, string Etag)> GetStateAsync(string service, string key, CancellationToken cancellationToken = default)

Parameters

service string

The service name.

key string

The state key.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<(string Value, string Etag)>

Tuple of (value, etag).

GetTriggerAsync(string, CancellationToken)

Retrieves a scheduled trigger's details.

public Task<GetTriggerResponse> GetTriggerAsync(string name, CancellationToken cancellationToken = default)

Parameters

name string
cancellationToken CancellationToken

Returns

Task<GetTriggerResponse>

InvokeAsync(string, string, Dictionary<string, object?>?)

Invokes a method on a service asynchronously.

public Task<Dictionary<string, object?>> InvokeAsync(string service, string method, Dictionary<string, object?>? requestData = null)

Parameters

service string

The service name.

method string

The method name.

requestData Dictionary<string, object>

Optional request data as dictionary.

Returns

Task<Dictionary<string, object>>

The response as a dictionary.

Remarks

The polymorphic Dictionary<string, object?> payload is (de)serialized via Virtufin.Api.Client.ApiClient.JsonOptions, which sets an explicit DefaultJsonTypeInfoResolver so reflection-based dispatch works regardless of the process-wide IsReflectionEnabledByDefault flag. See Virtufin.Api.Client.ApiClient.JsonOptions for the AOT caveat.

Exceptions

InvalidOperationException

Thrown when the invocation fails.

ListConfigServicesAsync(CancellationToken)

Lists every registered service, including non-dialable entries (those that exist only to resolve Dapr component names).

public Task<ListConfigServicesResponse> ListConfigServicesAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

Task<ListConfigServicesResponse>

Remarks

Contrast ListServicesAsync(), which returns only the backends the gateway can actually invoke.

ListMethodsAsync(string)

Lists all methods for a given service asynchronously.

public Task<List<Dictionary<string, object?>>> ListMethodsAsync(string service)

Parameters

service string

The service name.

Returns

Task<List<Dictionary<string, object>>>

List of method information dictionaries.

ListServicesAsync()

Lists all available services asynchronously.

public Task<List<string>> ListServicesAsync()

Returns

Task<List<string>>

List of service names.

ListTriggersAsync(CancellationToken)

Lists all scheduled triggers.

public Task<ListTriggersResponse> ListTriggersAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

Task<ListTriggersResponse>

PublishEventAsync(string, CloudEvent, CancellationToken)

Publishes a CloudEvent to a topic asynchronously.

public Task<PublishResponse> PublishEventAsync(string topic, CloudEvent cloudevent, CancellationToken cancellationToken = default)

Parameters

topic string

The topic name.

cloudevent CloudEvent

The CloudEvent proto to publish.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<PublishResponse>

PublishResponse with success status.

PublishWithResultAsync(string, CloudEvent, string, TimeSpan?, string?, CancellationToken)

Publishes to a topic and waits for a correlated response on a reply topic. Implements the request-reply pattern over pub/sub using correlation IDs. Sets correlationid and replytopic as CloudEvent attributes before publishing.

public Task<SubscribeResponse> PublishWithResultAsync(string topic, CloudEvent cloudevent, string replyTopic, TimeSpan? timeout = null, string? correlationId = null, CancellationToken cancellationToken = default)

Parameters

topic string

The topic to publish the request to.

cloudevent CloudEvent

The CloudEvent proto to publish.

replyTopic string

The topic to listen for responses on.

timeout TimeSpan?

Maximum time to wait for a response (default: 30s).

correlationId string

Optional correlation ID (auto-generated if null).

cancellationToken CancellationToken

Cancellation token.

Returns

Task<SubscribeResponse>

The correlated SubscribeResponse.

Exceptions

TimeoutException

Thrown if no response arrives within the timeout.

QueryStateAsync(string, string, int, CancellationToken)

Gets all state key-value pairs asynchronously for a service.

public Task<List<StateItemDto>> QueryStateAsync(string service, string query, int limit = 0, CancellationToken cancellationToken = default)

Parameters

service string

The service name.

query string

The Dapr JSON query string.

limit int

Max results (0 = no limit).

cancellationToken CancellationToken

Cancellation token.

Returns

Task<List<StateItemDto>>

List of state items with key, value, etag.

SaveStateAsync(string, string, string, string?, bool, bool, ChangeNotification?, CancellationToken)

Saves state and broadcasts a change event to subscribers asynchronously.

public Task<SaveStateResponse> SaveStateAsync(string service, string key, string value, string? etag = null, bool publishChange = false, bool includeValue = false, ChangeNotification? change = null, CancellationToken cancellationToken = default)

Parameters

service string

The service name.

key string

The state key.

value string

The state value.

etag string

Optional etag for concurrency.

publishChange bool

If true, a state.change event is published. Default false.

includeValue bool

If true, the value is included in the state change event payload. Only relevant when publishChange=true.

change ChangeNotification

Optional. With publishChange, selects where the notification goes. Unset means the Tier 0 state.change topic, correct for infra state. For domain state (positions, portfolios, orders) supply a ChangeNotification carrying both a topic and a CloudEvent: the API publishes that event verbatim after the write and skips state.change. It cannot build the event itself -- it has the key and the bytes but not the scenario, world markers, clock type, or your service identity. Tier 0 events carry no version, so consuming the value without a read-back assumes writes to that key are serialized; carry a monotonic token in your own event if you need ordering. Publication is at-most-once and not atomic with the write.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<SaveStateResponse>

SaveStateResponse with success status.

ScheduleTriggerAsync(string, string, string?, string?, int, string?, CancellationToken)

Schedules a recurring trigger. When it fires, the API publishes an empty CloudEvent to targetTopic.

public Task<ScheduleTriggerResponse> ScheduleTriggerAsync(string name, string targetTopic, string? schedule = null, string? dueTime = null, int repeats = 0, string? ttl = null, CancellationToken cancellationToken = default)

Parameters

name string

Trigger name, unique per deployment.

targetTopic string

Topic the fired trigger publishes to.

schedule string

A 6-field cron expression or an @every duration.

dueTime string

Optional first-fire time.

repeats int

Optional repeat count; 0 means unlimited.

ttl string

Optional time-to-live.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<ScheduleTriggerResponse>

Remarks

Errors are in-band: the gRPC status is OK and failure is signalled by status.success == false. Check it.

Subscribe(IEnumerable<string>?, CancellationToken)

Subscribes to one or more pub/sub topics.

public AsyncServerStreamingCall<SubscribeResponse> Subscribe(IEnumerable<string>? topics = null, CancellationToken cancellationToken = default)

Parameters

topics IEnumerable<string>

Topics to subscribe to. Filtering is by topic only -- SubscribeRequest carries no service or event-type filter, so discriminate further on cloudevent.type. An empty list is not "all topics": the server defaults it to state.change, so name your topics explicitly. (services and eventTypes parameters were removed -- they were accepted, documented as filters, and silently discarded.)

cancellationToken CancellationToken

Cancellation token.

Returns

AsyncServerStreamingCall<SubscribeResponse>

The async call handle. Dispose to cancel subscription.

SubscribeAsync(IStreamEventHandler, IEnumerable<string>?, CancellationToken)

Subscribes to events with a handler callback.

public Task SubscribeAsync(IStreamEventHandler handler, IEnumerable<string>? topics = null, CancellationToken cancellationToken = default)

Parameters

handler IStreamEventHandler

Handler to receive events.

topics IEnumerable<string>

Topics to subscribe to. Filtering is by topic only -- SubscribeRequest carries no service or event-type filter, so discriminate further on cloudevent.type. An empty list is not "all topics": the server defaults it to state.change, so name your topics explicitly. (services and eventTypes parameters were removed -- they were accepted, documented as filters, and silently discarded.)

cancellationToken CancellationToken

Cancellation token.

Returns

Task

Task that completes when subscription is cancelled.

SubscribeToTopic(string, CancellationToken)

Subscribes to a pub/sub topic and streams events.

public AsyncServerStreamingCall<SubscribeResponse> SubscribeToTopic(string topic, CancellationToken cancellationToken = default)

Parameters

topic string

The topic name.

cancellationToken CancellationToken

Cancellation token.

Returns

AsyncServerStreamingCall<SubscribeResponse>

Async streaming call for SubscribeResponse. Dispose to cancel.

TryGetMember(GetMemberBinder, out object?)

Dynamic property access returns a ServiceClient for the named service.

public override bool TryGetMember(GetMemberBinder binder, out object? result)

Parameters

binder GetMemberBinder
result object

Returns

bool

UnsubscribeFromTopicAsync(string, CancellationToken)

Unsubscribes from a pub/sub topic.

public Task<UnsubscribeResponse> UnsubscribeFromTopicAsync(string subscriptionId, CancellationToken cancellationToken = default)

Parameters

subscriptionId string

The subscription ID to cancel.

cancellationToken CancellationToken

Cancellation token.

Returns

Task<UnsubscribeResponse>

UnsubscribeResponse with success status.