Documentation
¶
Overview ¶
Package sqs solves the operational friction of using AWS SQS directly from the aws-sdk-go-v2 in application code. It wraps github.com/aws/aws-sdk-go-v2/service/sqs with a small, focused API that covers the common queue workflow: send, receive, decode, acknowledge (delete), and health-check.
Problem ¶
Raw SQS integration requires repetitive boilerplate across services: queue and endpoint setup, FIFO message-group handling, long-poll configuration, visibility-timeout tuning, payload serialization, and error-safe delete logic. Teams often re-implement this stack in each service, which leads to subtle behavior drift and harder testing.
This package standardizes that flow into one client with explicit options and safe defaults.
How It Works ¶
New creates a Client bound to a queue URL and optional message-group ID.
- queueURL must be a valid absolute URL. For FIFO queues (URL ends with `.fifo`), a valid message-group ID is required; for standard queues it must be empty, and a non-empty value is rejected with ErrUnexpectedMessageGroupID. Argument validation runs before any AWS configuration is loaded.
- The AWS region is derived from the queue URL when it is not set explicitly, so callers rarely need to repeat it; an explicit region supplied via WithAWSOptions still takes precedence.
- For FIFO queues, Client.Send and Client.SendData do not set a MessageDeduplicationId, so the queue must have ContentBasedDeduplication enabled; otherwise supply an explicit per-message deduplication ID via Client.SendWithDeduplicationID or Client.SendDataWithDeduplicationID.
- Long polling and visibility are configurable via WithWaitTimeSeconds and WithVisibilityTimeout, with defaults of DefaultWaitTimeSeconds (20s) and DefaultVisibilityTimeout (600s).
- Payloads can be sent/received as raw strings (Client.Send, Client.Receive) or typed data (Client.SendData, Client.ReceiveData) through pluggable encode/decode hooks.
- Configuration and argument problems are reported as exported sentinel errors (see ErrInvalidQueueURL and the others in this package) that callers can match with errors.Is.
Receive flow behavior:
- Client.Receive returns nil,nil when no message arrives within the long-poll window.
- Client.ReceiveData returns an empty receipt handle when no message is available.
- After successful processing, callers should acknowledge via Client.Delete using the receipt handle.
- If decode fails, Client.ReceiveData still returns the receipt handle so callers can choose whether to delete or re-queue according to their policy.
Key Features ¶
- Simple SQS workflow API: send, receive, delete, and health check.
- FIFO-aware safety: validates message-group usage for FIFO queues and supports explicit per-message deduplication IDs.
- Typed payload support with customizable serialization/encryption via WithMessageEncodeFunc and WithMessageDecodeFunc.
- Endpoint and AWS config customization via WithAWSOptions, WithSrvOptionFuncs, WithEndpointMutable, and WithEndpointImmutable for local testing and advanced deployments.
- Full client injection via WithSQSClient for tests and advanced integrations; when set, the AWS configuration is not loaded and the AWS and service options above are ignored.
- Health probe support through Client.HealthCheck, which verifies queue accessibility in the configured region.
Usage ¶
c, err := sqs.New(ctx,
"https://sqs.us-east-1.amazonaws.com/123456789012/my-queue",
"", // non-FIFO queue
sqs.WithWaitTimeSeconds(20),
sqs.WithVisibilityTimeout(300),
)
if err != nil {
return err
}
// Send typed payload
if err := c.SendData(ctx, event); err != nil {
return err
}
// Receive typed payload
var msg Event
receiptHandle, err := c.ReceiveData(ctx, &msg)
if err != nil {
return err
}
if receiptHandle != "" {
_ = c.Delete(ctx, receiptHandle)
}
This package is ideal for Go services that need a minimal, consistent, production-friendly abstraction over SQS without losing access to AWS SDK customization.
Example ¶
package main
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
awssqs "github.com/aws/aws-sdk-go-v2/service/sqs"
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
"github.com/tecnickcom/nurago/pkg/sqs"
)
// exampleSQSClient is a minimal in-memory stand-in for the AWS SQS client,
// implementing only the sqs.SQS interface. Real code would let New build the
// client from aws.Config instead.
type exampleSQSClient struct {
body string
}
func (c *exampleSQSClient) SendMessage(
_ context.Context,
params *awssqs.SendMessageInput,
_ ...func(*awssqs.Options),
) (*awssqs.SendMessageOutput, error) {
c.body = aws.ToString(params.MessageBody)
return &awssqs.SendMessageOutput{}, nil
}
func (c *exampleSQSClient) ReceiveMessage(
_ context.Context,
_ *awssqs.ReceiveMessageInput,
_ ...func(*awssqs.Options),
) (*awssqs.ReceiveMessageOutput, error) {
return &awssqs.ReceiveMessageOutput{
Messages: []types.Message{{
Body: aws.String(c.body),
ReceiptHandle: aws.String("example-receipt-handle"),
}},
}, nil
}
func (c *exampleSQSClient) DeleteMessage(
_ context.Context,
_ *awssqs.DeleteMessageInput,
_ ...func(*awssqs.Options),
) (*awssqs.DeleteMessageOutput, error) {
return &awssqs.DeleteMessageOutput{}, nil
}
func (c *exampleSQSClient) GetQueueAttributes(
_ context.Context,
_ *awssqs.GetQueueAttributesInput,
_ ...func(*awssqs.Options),
) (*awssqs.GetQueueAttributesOutput, error) {
return &awssqs.GetQueueAttributesOutput{}, nil
}
func main() {
// A caller would normally configure a real client via options such as
// WithAWSOptions or WithEndpointMutable (and the region would be derived from
// the queue URL); here an injected client keeps the example self-contained, so
// no AWS configuration is loaded.
c, err := sqs.New(
context.TODO(),
"https://sqs.us-east-1.amazonaws.com/123456789012/my-queue",
"", // standard (non-FIFO) queue: no message group ID
sqs.WithSQSClient(&exampleSQSClient{}),
)
if err != nil {
fmt.Println("error:", err)
return
}
err = c.Send(context.TODO(), "hello world")
if err != nil {
fmt.Println("error:", err)
return
}
msg, err := c.Receive(context.TODO())
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(msg.Body)
// After processing, acknowledge the message by deleting it.
err = c.Delete(context.TODO(), msg.ReceiptHandle)
if err != nil {
fmt.Println("error:", err)
return
}
}
Output: hello world
Index ¶
- Constants
- Variables
- func DefaultMessageDecodeFunc(_ context.Context, msg string, data any) error
- func DefaultMessageEncodeFunc(_ context.Context, data any) (string, error)
- func MessageDecode(msg string, data any) error
- func MessageEncode(data any) (string, error)
- type Client
- func (c *Client) Delete(ctx context.Context, receiptHandle string) error
- func (c *Client) HealthCheck(ctx context.Context) error
- func (c *Client) Receive(ctx context.Context) (*Message, error)
- func (c *Client) ReceiveData(ctx context.Context, data any) (string, error)
- func (c *Client) Send(ctx context.Context, message string) error
- func (c *Client) SendData(ctx context.Context, data any) error
- func (c *Client) SendDataWithDeduplicationID(ctx context.Context, data any, dedupID string) error
- func (c *Client) SendWithDeduplicationID(ctx context.Context, message, dedupID string) error
- type Message
- type Option
- func WithAWSOptions(opt awsopt.Options) Option
- func WithEndpointImmutable(url string) Option
- func WithEndpointMutable(url string) Option
- func WithMessageDecodeFunc(f TDecodeFunc) Option
- func WithMessageEncodeFunc(f TEncodeFunc) Option
- func WithSQSClient(client SQS) Option
- func WithSrvOptionFuncs(opt ...SrvOptionFunc) Option
- func WithVisibilityTimeout(t int32) Option
- func WithWaitTimeSeconds(t int32) Option
- type SQS
- type SrvOptionFunc
- type TDecodeFunc
- type TEncodeFunc
Examples ¶
Constants ¶
const ( // DefaultWaitTimeSeconds is the default duration (in seconds) for which the call waits for a message to arrive in the queue before returning. // This must be between 0 and 20 seconds. DefaultWaitTimeSeconds = 20 // DefaultVisibilityTimeout is the default duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. DefaultVisibilityTimeout = 600 )
Variables ¶
var ( // ErrInvalidQueueURL is returned by New when queueURL is empty, unparseable, // or lacks a scheme or host. ErrInvalidQueueURL = errors.New("sqs: invalid queue URL") // ErrMissingMessageGroupID is returned by New when a FIFO queue URL is given // without a valid message group ID. ErrMissingMessageGroupID = errors.New("sqs: a valid message group ID is required for a FIFO queue") // ErrUnexpectedMessageGroupID is returned by New when a message group ID is // supplied for a standard (non-FIFO) queue, which does not use message groups. ErrUnexpectedMessageGroupID = errors.New("sqs: a message group ID must not be set for a standard queue") // ErrDedupIDNotAllowed is returned by SendWithDeduplicationID and // SendDataWithDeduplicationID when the target queue is not a FIFO queue. ErrDedupIDNotAllowed = errors.New("sqs: a message deduplication ID can only be used with FIFO queues") // ErrInvalidDedupID is returned by SendWithDeduplicationID and // SendDataWithDeduplicationID when the deduplication ID is empty or invalid. ErrInvalidDedupID = errors.New("sqs: invalid message deduplication ID") // ErrNilEncodeFunc is returned by New when the message encode function is nil. ErrNilEncodeFunc = errors.New("sqs: nil message encode function") // ErrNilDecodeFunc is returned by New when the message decode function is nil. ErrNilDecodeFunc = errors.New("sqs: nil message decode function") // ErrInvalidWaitTime is returned by New when waitTimeSeconds is outside the // valid 0..20 seconds range. ErrInvalidWaitTime = errors.New("sqs: waitTimeSeconds must be between 0 and 20 seconds") // ErrInvalidVisibilityTimeout is returned by New when visibilityTimeout is // outside the valid 0..43200 seconds range. ErrInvalidVisibilityTimeout = errors.New("sqs: visibilityTimeout must be between 0 and 43200 seconds") // ErrQueueNotResponding is returned by HealthCheck when the queue does not // return the expected attribute. ErrQueueNotResponding = errors.New("sqs: the queue is not responding") )
Exported sentinel errors returned by this package. Match them with errors.Is.
Functions ¶
func DefaultMessageDecodeFunc ¶
DefaultMessageDecodeFunc is the default deserializer used by ReceiveData.
func DefaultMessageEncodeFunc ¶
DefaultMessageEncodeFunc is the default serializer used by SendData.
func MessageDecode ¶
MessageDecode decodes a MessageEncode payload into data, which must be a pointer.
func MessageEncode ¶
MessageEncode encodes and serializes data into an SQS-compatible string payload.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client wraps AWS SQS operations and typed message encoding/decoding for a single queue URL.
func New ¶
New builds a client for queueURL and validates FIFO message-group constraints.
queueURL must be a valid absolute URL. msgGroupID is required (and must be a valid FIFO group ID) when queueURL targets a FIFO queue, and must be empty for a standard queue. Cheap argument validation runs before any AWS configuration is loaded, so misconfiguration fails fast.
It returns ErrInvalidQueueURL when queueURL is empty or malformed, ErrMissingMessageGroupID when a FIFO queue is given without a valid group ID, and ErrUnexpectedMessageGroupID when a group ID is set for a standard queue. Invalid options surface ErrNilEncodeFunc, ErrNilDecodeFunc, ErrInvalidWaitTime, or ErrInvalidVisibilityTimeout.
The returned Client is safe for concurrent use.
func (*Client) HealthCheck ¶
HealthCheck verifies queue reachability by fetching a known queue attribute.
It returns ErrQueueNotResponding when the queue call succeeds but does not return the expected attribute; the underlying AWS error is wrapped otherwise.
func (*Client) Receive ¶
Receive retrieves one raw message from the queue with configured wait/visibility settings. Returns nil message when no message is available within waitTimeSeconds.
func (*Client) ReceiveData ¶
ReceiveData receives one message, decodes its payload into data, and returns the receipt handle. If decoding fails, receipt handle is still returned so callers can decide whether to delete or requeue.
func (*Client) Send ¶
Send publishes a raw string message to the queue.
NOTE: no MessageDeduplicationId is set, so for FIFO queues this requires ContentBasedDeduplication to be enabled on the queue; otherwise AWS rejects the request. Use SendWithDeduplicationID to supply an explicit deduplication ID instead.
func (*Client) SendData ¶
SendData encodes data via configured codec and publishes it to the queue.
NOTE: no MessageDeduplicationId is set, so for FIFO queues this requires ContentBasedDeduplication to be enabled on the queue; otherwise AWS rejects the request. Use SendDataWithDeduplicationID to supply an explicit deduplication ID instead.
func (*Client) SendDataWithDeduplicationID ¶
SendDataWithDeduplicationID encodes data via configured codec and publishes it to the queue with an explicit MessageDeduplicationId. See SendWithDeduplicationID for the FIFO-queue deduplication constraints.
func (*Client) SendWithDeduplicationID ¶
SendWithDeduplicationID publishes a raw string message to the queue with an explicit MessageDeduplicationId.
It is only valid for FIFO queues and is required when the queue does not have ContentBasedDeduplication enabled. Messages sent with the same deduplication ID within the 5-minute deduplication interval are accepted but not delivered again. The dedupID can contain up to 128 alphanumeric and punctuation characters.
It returns ErrDedupIDNotAllowed when the queue is not a FIFO queue and ErrInvalidDedupID when dedupID is empty or malformed.
type Message ¶
type Message struct {
// Body is the message content and can contain: JSON, XML or plain text.
Body string
// ReceiptHandle is the identifier used to delete the message.
ReceiptHandle string
}
Message holds a received payload and the receipt handle used for deletion.
type Option ¶
type Option func(*cfg)
Option applies a configuration change to the internal SQS client settings.
func WithAWSOptions ¶
WithAWSOptions appends awsopt options used to build aws.Config.
func WithEndpointImmutable ¶
WithEndpointImmutable installs a fixed EndpointResolverV2 for deterministic endpoint routing.
func WithEndpointMutable ¶
WithEndpointMutable sets BaseEndpoint while preserving SDK endpoint mutability.
func WithMessageDecodeFunc ¶
func WithMessageDecodeFunc(f TDecodeFunc) Option
WithMessageDecodeFunc overrides the deserializer used by ReceiveData. The data argument passed to ReceiveData must be a pointer to the expected type.
func WithMessageEncodeFunc ¶
func WithMessageEncodeFunc(f TEncodeFunc) Option
WithMessageEncodeFunc overrides the serializer used by SendData.
func WithSQSClient ¶
WithSQSClient injects a custom SQS implementation.
This is primarily useful for tests and advanced integrations where the caller needs full control over request behavior without creating a real sqs.Client from aws.Config. When set, the injected client is used as-is: the AWS configuration is not loaded and the AWS/service options (WithAWSOptions, WithSrvOptionFuncs, WithEndpointMutable, WithEndpointImmutable) are ignored.
func WithSrvOptionFuncs ¶
func WithSrvOptionFuncs(opt ...SrvOptionFunc) Option
WithSrvOptionFuncs appends service-level sqs.Options mutators.
func WithVisibilityTimeout ¶
WithVisibilityTimeout sets message invisibility duration in seconds after receive. Values range: 0 to 43200. Maximum: 12 hours.
func WithWaitTimeSeconds ¶
WithWaitTimeSeconds sets long-poll wait duration in seconds for ReceiveMessage calls. Values range: 0 to 20 seconds.
type SQS ¶
type SQS interface {
DeleteMessage(ctx context.Context, params *sqs.DeleteMessageInput, optFns ...func(*sqs.Options)) (*sqs.DeleteMessageOutput, error)
GetQueueAttributes(ctx context.Context, params *sqs.GetQueueAttributesInput, optFns ...func(*sqs.Options)) (*sqs.GetQueueAttributesOutput, error)
ReceiveMessage(ctx context.Context, params *sqs.ReceiveMessageInput, optFns ...func(*sqs.Options)) (*sqs.ReceiveMessageOutput, error)
SendMessage(ctx context.Context, params *sqs.SendMessageInput, optFns ...func(*sqs.Options)) (*sqs.SendMessageOutput, error)
}
SQS defines the AWS SDK SQS calls used by Client.
type SrvOptionFunc ¶
SrvOptionFunc aliases an AWS SDK SQS service option mutator.
type TDecodeFunc ¶
TDecodeFunc is the type of function used to replace the default message decoding function used by ReceiveData().