In this tutorial, we will look at how we can use the AWS Go SDK to perform various operations on AWS SQS.

Table of contents

Prerequisites

  • Install AWS Go SDK: Run go get -u github.com/aws/aws-sdk-go/... to install the SDK
  • AWS Credentials: If you haven’t setup AWS credentials before, this resource from AWS is helpful.

How to create a new SQS queue?

We will be using the CreateQueue method from the SDK to create a new SQS queue. Some of the important parameters to keep in mind while using this method:

  • QueueName: Name of the queue that you want to create
  • Attributes: Specify the attribute values for the queue. Some of the commonly used attributes are:
    • DelaySeconds: Messages are delayed by this value before being delivered.
    • RedrivePolicy: Specifies the dead-letter queue functionality
    • VisibilityTimeout: Visibility timeout for the queue in seconds. This is the period of time where a particular message is only visible to a single consumer.

In the following example, we will create a queue name my-new-queue with DelaySeconds set to 0 and VisibilityTimeout set to 60 seconds.


package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func CreateQueue(sess *session.Session, queueName string) (*sqs.CreateQueueOutput, error) {
	sqsClient := sqs.New(sess)
	result, err := sqsClient.CreateQueue(&sqs.CreateQueueInput{
		QueueName: &queueName,
		Attributes: map[string]*string{
			"DelaySeconds":      aws.String("0"),
			"VisibilityTimeout": aws.String("60"),
		},
	})

	if err != nil {
		return nil, err
	}

	return result, nil
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	queueName := "my-new-queue"
	createRes, err := CreateQueue(sess, queueName)
	if err != nil {
		fmt.Printf("Got an error while trying to create queue: %v", err)
		return
	}

	fmt.Println("Created a new queue with url: " + *createRes.QueueUrl)
}

Output:

Created a new queue with url: https://us-west-2.queue.amazonaws.com/xxxx/my-new-queue

How to get the URL of an SQS queue?

Most of the SQS APIs require the QueueUrl so we will use the GetQueueUrl method to retrieve the URL of the queue using the QueueName


package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func GetQueueURL(sess *session.Session, queue string) (*sqs.GetQueueUrlOutput, error) {
	sqsClient := sqs.New(sess)

	result, err := sqsClient.GetQueueUrl(&sqs.GetQueueUrlInput{
		QueueName: &queue,
	})

	if err != nil {
		return nil, err
	}

	return result, nil
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	queueName := "my-new-queue"

	urlRes, err := GetQueueURL(sess, queueName)
	if err != nil {
		fmt.Printf("Got an error while trying to create queue: %v", err)
		return
	}

	fmt.Println("Got Queue URL: " + *urlRes.QueueUrl)
}

Output:

Got queue URL: https://us-west-2.queue.amazonaws.com/xxxx/my-new-queue

How to send a message to an SQS queue?

We will be using the SendMessage method from the SDK to send a message to the SQS queue. Some of the important parameters to keep in mind while using this method:

  • QueueUrl: URL of the queue we want to send a message to
  • MessageBody: The message we want to send. The message should be serialized as a String.

package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func GetQueueURL(sess *session.Session, queue string) (*sqs.GetQueueUrlOutput, error) {
	sqsClient := sqs.New(sess)

	result, err := sqsClient.GetQueueUrl(&sqs.GetQueueUrlInput{
		QueueName: &queue,
	})

	if err != nil {
		return nil, err
	}

	return result, nil
}

func SendMessage(sess *session.Session, queueUrl string, messageBody string) error {
	sqsClient := sqs.New(sess)

	_, err := sqsClient.SendMessage(&sqs.SendMessageInput{
		QueueUrl:    &queueUrl,
		MessageBody: aws.String(messageBody),
	})

	return err
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	queueName := "my-new-queue"

	urlRes, err := GetQueueURL(sess, queueName)
	if err != nil {
		fmt.Printf("Got an error while trying to create queue: %v", err)
		return
	}

    messageBody := "This is a test message"
	err = SendMessage(sess, *urlRes.QueueUrl, messageBody)
	if err != nil {
		fmt.Printf("Got an error while trying to send message to queue: %v", err)
		return
	}

	fmt.Println("Message sent successfully")
}

Output:


Message sent successfully


How to receive a message from an SQS queue?

We will be using the ReceiveMessage method from the SDK to send a message to the SQS queue. Some of the important parameters to keep in mind while using this method:

  • QueueUrl: URL of the queue we want to send a message to
  • MaxNumberOfMessages: The maximum number of messages to retrieve.

package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func GetQueueURL(sess *session.Session, queue string) (*sqs.GetQueueUrlOutput, error) {
	sqsClient := sqs.New(sess)

	result, err := sqsClient.GetQueueUrl(&sqs.GetQueueUrlInput{
		QueueName: &queue,
	})

	if err != nil {
		return nil, err
	}

	return result, nil
}

func GetMessages(sess *session.Session, queueUrl string, maxMessages int) (*sqs.ReceiveMessageOutput, error) {
	sqsClient := sqs.New(sess)

	msgResult, err := sqsClient.ReceiveMessage(&sqs.ReceiveMessageInput{
		QueueUrl:            &queueUrl,
		MaxNumberOfMessages: aws.Int64(1),
	})

	if err != nil {
		return nil, err
	}

	return msgResult, nil
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	queueName := "my-new-queue"

	urlRes, err := GetQueueURL(sess, queueName)
	if err != nil {
		fmt.Printf("Got an error while trying to create queue: %v", err)
		return
	}

    maxMessages := 1
	msgRes, err := GetMessages(sess, *urlRes.QueueUrl, maxMessages)
	if err != nil {
		fmt.Printf("Got an error while trying to retrieve message: %v", err)
		return
	}

	fmt.Println("Message Body: " + *msgRes.Messages[0].Body)
	fmt.Println("Message Handle: " + *msgRes.Messages[0].ReceiptHandle)
}

Output:

Message Body: This is a test message
Message Handle: AQEB2qasreSZ3t3iqVh....

How to delete a message from a SQS queue?

Receiving a message from a queue in SQS doesn’t automatically delete a message. Another consumer can also retrieve the same message after the VisibilityTimeout expires. To ensure, no other consumer retrieves the same message, we need to delete the message after consuming it.

We will be using DeleteMessage to delete the message from the SQS queue. We also need to provide the ReceiptHandle as an argument for the method.


package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func DeleteMessage(sess *session.Session, queueUrl string, messageHandle *string) error {
	sqsClient := sqs.New(sess)

	_, err := sqsClient.DeleteMessage(&sqs.DeleteMessageInput{
		QueueUrl:      &queueUrl,
		ReceiptHandle: messageHandle,
	})

	return err
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	queueName := "my-new-queue"

	urlRes, err := GetQueueURL(sess, queueName)
	if err != nil {
		fmt.Printf("Got an error while trying to create queue: %v", err)
		return
	}

    maxMessages := 1
	msgRes, err := GetMessages(sess, *urlRes.QueueUrl, maxMessages)
	if err != nil {
		fmt.Printf("Got an error while trying to retrieve message: %v", err)
		return
	}

    receiptHandle := msgRes.Messages[0].ReceiptHandle
	err = DeleteMessage(sess, *urlRes.QueueUrl, receiptHandle)
	if err != nil {
		fmt.Printf("Got an error while trying to delete message: %v", err)
		return
	}

	fmt.Println("Deleted message with handle: " + *receiptHandle)
}

Output


Deleted message with handle: AQEB2qasr....


How to remove all messages from an SQS queue?

The SDK provides the PurgeQueue method to delete all messages from the Queue.


package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func PurgeQueue(sess *session.Session, queueUrl string, messageHandle *string) error {
	sqsClient := sqs.New(sess)

	_, err := sqsClient.DeleteMessage(&sqs.DeleteMessageInput{
		QueueUrl:      &queueUrl,
		ReceiptHandle: messageHandle,
	})

	return err
}

func main() {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: "default",
		Config: aws.Config{
			Region: aws.String("us-west-2"),
		},
	})

	if err != nil {
		fmt.Printf("Failed to initialize new session: %v", err)
		return
	}

	queueName := "my-new-queue"

	urlRes, err := GetQueueURL(sess, queueName)
	if err != nil {
		fmt.Printf("Got an error while trying to create queue: %v", err)
		return
	}

    maxMessages := 1
	msgRes, err := GetMessages(sess, *urlRes.QueueUrl, maxMessages)
	if err != nil {
		fmt.Printf("Got an error while trying to retrieve message: %v", err)
		return
	}

    receiptHandle := msgRes.Messages[0].ReceiptHandle
	err = DeleteMessage(sess, *urlRes.QueueUrl, receiptHandle)
	if err != nil {
		fmt.Printf("Got an error while trying to delete message: %v", err)
		return
	}

	fmt.Println("Deleted message with handle: " + *receiptHandle)
}

Output


Deleted message with handle: AQEB2qasr....