In previous articles, I covered Migrating to Brighter V10 with AWS SNS/SQS. This guide focuses on integrating to Brighter V10 with AWS SDK v4.
AWS SDK v4
AWS SDK v4 represents a significant evolution from previous versions with several important changes:
Enhanced Async Support: The SDK now fully embraces async/await patterns throughout, eliminating blocking calls and improving resource utilization
Modernized Dependency Injection: Improved integration with Microsoft.Extensions.DependencyInjection, making registration and configuration more straightforward
Performance Optimizations: Reduced memory allocation and improved throughput for high-volume messaging scenarios
Better Error Handling: More granular exception types and improved retry mechanisms
These changes required Brighter to create dedicated integration packages to maintain compatibility while taking advantage of the new SDK's capabilities.
Why Brighter has 2 package for AWS SNS/SQS
Brighter provides two distinct AWS integration packages to accommodate different development needs:
Paramore.Brighter.MessagingGateway.AWSSQS - For AWS SDK v3 integration
Paramore.Brighter.MessagingGateway.AWS.V4 - For AWS SDK v4 integration
There is no significant functional difference between the two packages in terms of Brighter's core messaging capabilities. The separation exists solely to support different AWS SDK versions, allowing teams to:
- Migrate to Brighter V10 without being forced to upgrade AWS SDK simultaneously
- Maintain compatibility with existing AWS SDK v3 dependencies
- Gradually adopt AWS SDK v4 at their own pace
Choose the package that aligns with your current AWS SDK version - the Brighter API surface remains consistent regardless of which AWS package you select.
Requirement
- .NET 8 or superior
- A .NET project with these NuGet packages
- Paramore.Brighter.MessagingGateway.AWS.V4: Enables AWS SDK V4 SNS/SQS integration.
- Paramore.Brighter.ServiceActivator.Extensions.DependencyInjection: Enable register Brighter with Microsoft DI.
- Paramore.Brighter.ServiceActivator.Extensions.Hosting: Hosts Brighter as a background service.
- Serilog.AspNetCore: For structured logging (optional but recommended).
Brighter Recap
Before continuing about AWS SNS/SQS configuration, let's recap what we already know about Brighter.
Request (Command/Event)
Define messages using IRequest
:
public class Greeting() : Event(Id.Random())
{
public string Name { get; set; } = string.Empty;
}
- Commands: Single-recipient operations (e.g.,
SendEmail
). - Events: Broadcast notifications (e.g.,
OrderShipped
).
Message Mapper (Optional)
Translates between Brighter messages and your app objects:
public class SqsFifoMapper : IAmAMessageMapperAsync<SqsFifoEvent>
{
public Task<Message> MapToMessageAsync(SqsFifoEvent request, Publication publication,
CancellationToken cancellationToken = new CancellationToken())
{
return Task.FromResult(new Message(new MessageHeader
{
MessageId = request.Id,
Topic = publication.Topic!,
PartitionKey = request.PartitionValue, // FIFO requirement
MessageType = MessageType.MT_EVENT,
TimeStamp = DateTimeOffset.UtcNow
},
new MessageBody(JsonSerializer.SerializeToUtf8Bytes(request, JsonSerialisationOptions.Options))));
}
public Task<SqsFifoEvent> MapToRequestAsync(Message message, CancellationToken cancellationToken = new CancellationToken())
{
return Task.FromResult(JsonSerializer.Deserialize<SqsFifoEvent>(message.Body.Bytes, JsonSerialisationOptions.Options)!);
}
public IRequestContext? Context { get; set; }
}
Request Handler
Processes incoming messages:
public class GreetingHandler(ILogger<GreetingHandler> logger) : RequestHandler<Greeting>
{
public override Greeting Handle(Greeting command)
{
logger.LogInformation("Hello {Name}", command.Name);
await processor.PostAsync(new Farewell { Name = command.Name }, cancellationToken: cancellationToken);
return base.Handle(command);
}
}
Configuring Brighter with AWS SNS/SQS
1. Connection Setup
Define AWS SNS connection details:
var connection = new AWSMessagingGatewayConnection(new BasicAWSCredentials("test", "test"),
RegionEndpoint.USEast1,
cfg => cfg.ServiceURL = "http://localhost:4566" // LocalStack
);
2. SQS Subscription
Subscribe to a SQS, in this sample I'll show to how to connect the SNS to SQS, SQS to SQS and SNS to SQS FIFO:
.AddConsumers(opt =>
{
opt.Subscriptions = [
// SNS → SQS
new SqsSubscription<Greeting>(
"greeting-subscription", // Optional
"greeting-queue", // SQS queue name
ChannelType.PubSub, // Required for SNS
"greeting.topic".ToValidSNSTopicName(), // SNS Topic Name
bufferSize: 2,
messagePumpType: MessagePumpType.Proactor),
// SQS → SQS (Point-to-Point)
new SqsSubscription<Farewell>(
new SubscriptionName("farawell-subscription"), // Optional
new ChannelName("farewell.queue"), // SQS queue name
ChannelType.PointToPoint, // Direct SQS
new RoutingKey("farewell.queue".ToValidSQSQueueName()), // SNS Topic Name
bufferSize: 2,
messagePumpType: MessagePumpType.Proactor),
// FIFO SNS → SQS
new SqsSubscription<SnsFifoEvent>(
new SubscriptionName("sns-sample-fifo-subscription"), // Optional
new ChannelName("sns-sample-fifo".ToValidSQSQueueName(true)), // SQS queue name
ChannelType.PubSub,
new RoutingKey("sns-sample-fifo".ToValidSNSTopicName(true)), // SNS Topic Name
bufferSize: 2,
messagePumpType: MessagePumpType.Proactor,
topicAttributes: new SnsAttributes { Type = SqsType.Fifo }, // FIFO
queueAttributes: new SqsAttributes(type: SqsType.Fifo)), // FIFO
];
opt.DefaultChannelFactory = new ChannelFactory(connection);
})
3. SNS/SQS Producer Configuration
Publish events to a topic, because we want to produce to multi publication type (SNS and SQS) we will need to use the CombinedProducerRegistryFactory
:
.AddProduces(opt =>
{
opt.ProducerRegistry = new CombinedProducerRegistryFactory(
// SNS Producers
new SnsMessageProducerFactory(connection, [
new SnsPublication<Greeting>
{
Topic = "greeting.topic".ToValidSNSTopicName(),
MakeChannels = OnMissingChannel.Create
},
new SnsPublication<SnsFifoEvent>
{
Topic = "sns-sample-fifo".ToValidSNSTopicName(true),
MakeChannels = OnMissingChannel.Create,
TopicAttributes = new SnsAttributes
{
Type = SqsType.Fifo
}
}
]),
// SQS Producers
new SqsMessageProducerFactory(connection, [
new SqsPublication<Farewell>
{
ChannelName = "farewell.queue".ToValidSQSQueueName(),
Topic = "farewell.queue".ToValidSQSQueueName(),
MakeChannels = OnMissingChannel.Create
}
])
).Create();
});
Conclusion
Integrating Brighter V10 with AWS SDK v4 provides a modern, efficient messaging infrastructure that leverages the latest AWS SDK improvements while maintaining Brighter's familiar command and event patterns. By understanding the subtle differences between the AWS SDK versions and following the configuration patterns outlined here, you can build robust, scalable messaging solutions with proper separation of concerns.
The dual-package approach ensures smooth migration paths whether you're starting fresh with SDK v4 or planning a gradual transition from SDK v3. With proper configuration of subscriptions and producers, Brighter handles the complex messaging infrastructure details, allowing you to focus on your business logic.
Top comments (0)