In this post we will present a to send messages to AWS SQS. We will include an interface, an implementation, and a stub. We've previously included an example for producer and consumer in Go, and here we provide a nice API that enables us to use this code both in production and in tests.
The interface is the minimal API required to send a message. In this interface we hide the AWS session connection, as well as the AWS SQS queue name, and include only the message details.
type SqsApi interface {
SendMessage(
attributes map[string]string,
data string,
)
}
The implementation uses an AWS session. Notice that there are several methods to get an AWS session, but in this implementation we use the simplest method.
package awssqs
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sqs"
)
type SqsImpl struct {
sqsClient *sqs.SQS
queueUrl string
}
func ProduceAwsSqsImpl(
queueUrl string,
) *SqsImpl {
awsSession, err := session.NewSession()
if err!= nil{
panic(err)
}
return &SqsImpl{
sqsClient: sqs.New(awsSession),
queueUrl: queueUrl,
}
}
func (s *SqsImpl) SendMessage(
attributes map[string]string,
data string,
) {
input := sqs.SendMessageInput{
MessageAttributes: make(map[string]*sqs.MessageAttributeValue),
MessageBody: aws.String(data),
QueueUrl: aws.String(s.queueUrl),
}
for key, value := range attributes {
input.MessageAttributes[key] = &sqs.MessageAttributeValue{
DataType: aws.String("String"),
StringValue: aws.String(value),
}
}
_, err := s.sqsClient.SendMessage(&input)
if err!= nil{
panic(err)
}
}
We also include a stub that can be used during tests:
type MessageData struct {
Attributes map[string]string
Data string
}
type SqsStub struct {
Messages []*MessageData
}
func ProduceAwsSqsStub() *SqsStub {
return &SqsStub{}
}
func (s *SqsStub) SendMessage(
attributes map[string]string,
data string,
) {
messageData := MessageData{
Attributes: attributes,
Data: data,
}
s.Messages = append(s.Messages, &messageData)
}