DEV Community

Cover image for Integration Brighter V10 with AWS SNS/SQS V4
Rafael Andrade
Rafael Andrade

Posted on

Integration Brighter V10 with AWS SNS/SQS V4

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

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;
}
Enter fullscreen mode Exit fullscreen mode
  • 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; }
}
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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
); 
Enter fullscreen mode Exit fullscreen mode

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);
})
Enter fullscreen mode Exit fullscreen mode

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();
});
Enter fullscreen mode Exit fullscreen mode

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)