integration servicebus queues - grecosoft/NetFusion GitHub Wiki
Message patterns where Commands are sent to Queues, are based on a message exchange agreement between the Subscriber and the Publisher. The subscriber defines the queue to which other microservices send commands for execution. In this case, the subscriber defines the queue and also subscribes to process the received commands. Commands are used to request an action, implemented by another microservice, to be executed and may or may not have a response. Since the subscriber declares the queue, and is the service responsible for processing the command, it is also responsible for defining the structure of the command. The command, created by the publishing microservice, will be populated with all the information required by the subscribing service. Command processing is based on the Competing-Consumer dispatch pattern where only one subscribing microservice is delivered the command message for processing.
This example shows sending a Command to a Subscriber defined queue where the Publishing service does not expect a response. The example defines a command named SendEmail representing a command sent to a Microservice responsible for delivering emails. Add the following command class to the Examples.ServiceBus.Domain/Commands directory:
using NetFusion.Messaging.Types;
namespace Examples.ServiceBus.Domain.Commands;
public class SendEmail : Command
{
public string Subject { get; }
public string FromAddress { get; }
public string[] ToAddresses { get; }
public string Message { get; }
public SendEmail(string subject, string fromAddress, string[] toAddresses, string message)
{
Subject = subject;
FromAddress = fromAddress;
ToAddresses = toAddresses;
Message = message;
}
}
The subscribing microservice defines the queue and a route specifying the method to be called when a command is sent to the queue. Define the following handler within this directory Examples.ServiceBus.App/Handlers:
using System;
using Examples.ServiceBus.Domain.Commands;
using NetFusion.Common.Extensions;
namespace Examples.ServiceBus.App.Handlers;
public class EmailHandler
{
public void OnSendEmail(SendEmail command)
{
Console.WriteLine(nameof(OnSendEmail));
Console.WriteLine(command.ToIndentedJson());
}
}
Define the following route to dispatch the received command to the above handler method when received on the associated queue:
DefineQueue<SendEmail>(route =>
{
route.ToConsumer<EmailHandler>(c => c.OnSendEmail, queue =>
{
queue.QueueName = "ProcessEmails";
});
});
The above routing completes the following:
- Define a queue named ProcessEmails.
- When a command is received on the ProcessEmails queue, it will be dispatched to the OnSendEmail method of the EmailHandler class.
Add the following code to the ServiceBusRouter OnDefineEntities method to specify, when a SendEmail command is sent, it should be delivered to the ProcessEmails queue:
protected override void OnDefineEntities()
{
RouteToQueue<SendEmail>("ProcessEmails");
}
Add a corresponding model to the following directory: Examples.ServiceBus.WebApi/Models:
using System.ComponentModel.DataAnnotations;
namespace Examples.ServiceBus.WebApi.Models;
public class SendEmailModel
{
[Required] public string Subject { get; set; } = string.Empty;
[Required] public string FromAddress { get; set; } = string.Empty;
[Required] public string[] ToAddresses { get; set; } = Array.Empty<string>();
[Required] public string Message { get; set; } = string.Empty;
}
namespace Examples.ServiceBus.WebApi.Controllers;
[ApiController, Route("api/[controller]")]
public class ExampleController : ControllerBase
{
private readonly IMessagingService _messaging;
public ExampleController(
IMessagingService messaging, )
{
_messaging = messaging;
}
[HttpPost("send/email")]
public async Task<IActionResult> SendEmail(SendEmailModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var command = new SendEmail(model.Subject, model.FromAddress, model.ToAddresses, model.Message);
await _messaging.SendAsync(command);
return Ok();
}
}
Complete the following to run the example microservice and send a HTTP Post request to the example controller:
cd ./Examples.ServiceBus/src/Examples.ServiceBus.WebApi/
dotnet run
Post the following requests to: http://localhost:5003/api/example/send/email
{
"subject": "Out of Coffee",
"fromAddress": "[email protected]",
"toAddresses": ["[email protected]", "[email protected]"],
"message": "More is needed ASAP!"
}