Outbound Messages Routing
By default Silverback routes the messages according to their type and the static configuration defined at startup. In some cases you may need more flexibility, being able to apply your own routing rules.
In such cases it is possible to either take advantage of the simple endpoint name resolvers or even implement a fully customized router.
Endpoint name resolver
Using an endpoint name resolver is fairly simple and just requires a slightly different configuration in the IProducerEndpoint.
Here below a few examples of custom routing. Please refer to the KafkaProducerEndpoint/IKafkaProducerEndpointBuilder or MqttProducerEndpoint/IMqttProducerEndpointBuilder API documentation for further information about all the possibilities.
public class MyEndpointsConfigurator : IEndpointsConfigurator
{
public void Configure(IEndpointsConfigurationBuilder builder) =>
builder
.AddKafkaEndpoints(endpoints => endpoints
.Configure(config =>
{
config.BootstrapServers = "PLAINTEXT://kafka:9092";
})
// Using a resolver function
.AddOutbound<OrderCreatedEvent>(endpoint => endpoint
.ProduceTo<OrderCreatedEvent>(envelope =>
{
if (envelope.Message.IsPriority)
return "priority-orders";
else
return "normal-orders";
}))
// Using format string and arguments function
.AddOutbound<OrderCreatedEvent>(endpoint => endpoint
.ProduceTo<OrderCreatedEvent>(
"orders-{0}",
envelope =>
{
if (envelope.Message.IsPriority)
return new[] { "priority" };
else
return new[] { "normal" };
}))
// Using a resolver class
.AddOutbound<OrderCreatedEvent>(endpoint => endpoint
.UseEndpointNameResolver<MyEndpointNameResolver>())
// Kafka only: using a partition resolver function
.AddOutbound<InventoryUpdateMessage>(endpoint => endpoint
.ProduceTo<InventoryUpdateMessage>(
_ => "topic1",
envelope =>
{
switch (envelope.Message.Supplier)
{
case "foo":
return 0;
case "bar":
return 1;
case "baz":
return 2;
}
}))));
}
Custom router
In the following example a custom router is used to route the messages according to their priority (a copy is also sent to a catch-all topic).
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddSilverback()
.WithConnectionToMessageBroker(options => options
.AddKafka())
.AddEndpointsConfigurator<MyEndpointsConfigurator>();
}
}
Alternatively, an actual router class can also be created to encapsulate the routing logic.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddSilverback()
.WithConnectionToMessageBroker(options => options
.AddKafka())
.AddEndpointsConfigurator<MyEndpointsConfigurator>()
.AddSingletonOutboundRouter<PrioritizedRouter>();
}
}