AWS SDK for Go v2 with 130+ service clients, Request/Send pattern, and context support.
import (
"context"
"crypto/md5"
"encoding/base64"
"fmt"
"io"
"os"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/awserr"
"github.com/aws/aws-sdk-go-v2/aws/external"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func uploadWithAllOptions(filename, bucket, key string) error {
cfg, err := external.LoadDefaultAWSConfig()
if err != nil {
return fmt.Errorf("config error: %w", err)
}
svc := s3.New(cfg)
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("file error: %w", err)
}
defer file.Close()
// Calculate MD5 for integrity check
hash := md5.New()
io.Copy(hash, file)
md5sum := base64.StdEncoding.EncodeToString(hash.Sum(nil))
file.Seek(0, 0) // Reset file pointer
// Get file info
stat, _ := file.Stat()
// Set timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
req := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Body: file,
ContentLength: aws.Int64(stat.Size()),
ContentType: aws.String("application/octet-stream"),
ContentMD5: aws.String(md5sum),
// Metadata (custom headers)
Metadata: map[string]string{
"uploaded-by": "my-app",
"version": "1.0",
},
// Storage class
StorageClass: s3.StorageClassStandardIa,
// Server-side encryption
ServerSideEncryption: s3.ServerSideEncryptionAes256,
// Tags
Tagging: aws.String("Environment=prod&Team=engineering"),
// ACL
ACL: s3.ObjectCannedACLPrivate,
})
req.SetContext(ctx)
_, err = req.Send()
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case s3.ErrCodeNoSuchBucket:
return fmt.Errorf("bucket %s does not exist", bucket)
case "AccessDenied":
return fmt.Errorf("access denied: check IAM permissions")
case "EntityTooLarge":
return fmt.Errorf("file too large (max 5GB for single upload)")
default:
return fmt.Errorf("upload failed [%s]: %s", aerr.Code(), aerr.Message())
}
}
return err
}
return nil
}import (
"github.com/aws/aws-sdk-go-v2/service/s3/s3manager"
)
func uploadLargeFile(filename, bucket, key string) error {
cfg, _ := external.LoadDefaultAWSConfig()
// Create uploader with custom options
uploader := s3manager.NewUploader(cfg, func(u *s3manager.Uploader) {
u.PartSize = 10 * 1024 * 1024 // 10MB parts (min 5MB)
u.Concurrency = 5 // 5 concurrent uploads
u.LeavePartsOnError = false // Cleanup failed parts
u.MaxUploadParts = 10000 // Max parts (AWS limit)
})
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
result, err := uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Body: file,
// Optional: Add metadata, encryption, etc.
Metadata: map[string]string{
"filename": filepath.Base(filename),
},
})
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
if aerr.Code() == s3.ErrCodeNoSuchUpload {
return fmt.Errorf("multipart upload was aborted")
}
}
return err
}
fmt.Printf("Uploaded to: %s (ETag: %s)\n", result.Location, *result.ETag)
return nil
}func downloadLargeFile(bucket, key, filename string) error {
cfg, _ := external.LoadDefaultAWSConfig()
downloader := s3manager.NewDownloader(cfg, func(d *s3manager.Downloader) {
d.PartSize = 10 * 1024 * 1024 // 10MB parts
d.Concurrency = 5 // 5 concurrent downloads
})
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
numBytes, err := downloader.Download(file, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return err
}
fmt.Printf("Downloaded %d bytes\n", numBytes)
return nil
}func generatePresignedURL(bucket, key string, expiry time.Duration) (string, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := s3.New(cfg)
// GET presigned URL
req := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
url, err := req.Presign(expiry)
if err != nil {
return "", err
}
return url, nil
}
// PUT presigned URL (for uploads)
func generateUploadURL(bucket, key string, expiry time.Duration) (string, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := s3.New(cfg)
req := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
return req.Presign(expiry)
}func listAllObjects(bucket string) ([]string, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := s3.New(cfg)
var keys []string
req := svc.ListObjectsV2Request(&s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
// Optional: Prefix, Delimiter, MaxKeys
})
p := req.Paginate()
for p.Next() {
page := p.CurrentPage().(*s3.ListObjectsV2Output)
for _, obj := range page.Contents {
keys = append(keys, *obj.Key)
}
}
if err := p.Err(); err != nil {
return nil, err
}
return keys, nil
}import "github.com/aws/aws-sdk-go-v2/service/dynamodb"
func queryUsersByStatus(tableName, status string) ([]map[string]dynamodb.AttributeValue, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := dynamodb.New(cfg)
var items []map[string]dynamodb.AttributeValue
req := svc.QueryRequest(&dynamodb.QueryInput{
TableName: aws.String(tableName),
IndexName: aws.String("status-index"), // GSI
KeyConditionExpression: aws.String("status = :status"),
ExpressionAttributeValues: map[string]dynamodb.AttributeValue{
":status": {S: aws.String(status)},
},
// Optional: FilterExpression, ProjectionExpression, ScanIndexForward
})
p := req.Paginate()
for p.Next() {
page := p.CurrentPage().(*dynamodb.QueryOutput)
items = append(items, page.Items...)
}
if err := p.Err(); err != nil {
return nil, err
}
return items, nil
}func conditionalUpdate(tableName, id, newValue string, expectedVersion int) error {
cfg, _ := external.LoadDefaultAWSConfig()
svc := dynamodb.New(cfg)
req := svc.UpdateItemRequest(&dynamodb.UpdateItemInput{
TableName: aws.String(tableName),
Key: map[string]dynamodb.AttributeValue{
"id": {S: aws.String(id)},
},
UpdateExpression: aws.String("SET #v = :newval, version = version + :inc"),
ConditionExpression: aws.String("version = :expected"),
ExpressionAttributeNames: map[string]string{
"#v": "value", // Use placeholder for reserved words
},
ExpressionAttributeValues: map[string]dynamodb.AttributeValue{
":newval": {S: aws.String(newValue)},
":expected": {N: aws.String(fmt.Sprintf("%d", expectedVersion))},
":inc": {N: aws.String("1")},
},
ReturnValues: dynamodb.ReturnValueAllNew,
})
resp, err := req.Send()
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
if aerr.Code() == "ConditionalCheckFailedException" {
return fmt.Errorf("version mismatch - item was modified concurrently")
}
}
return err
}
// resp.Attributes contains the updated item
return nil
}func batchGetItems(tableName string, ids []string) ([]map[string]dynamodb.AttributeValue, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := dynamodb.New(cfg)
// DynamoDB batch limit is 100 items
batchSize := 100
var allItems []map[string]dynamodb.AttributeValue
for i := 0; i < len(ids); i += batchSize {
end := i + batchSize
if end > len(ids) {
end = len(ids)
}
batch := ids[i:end]
keys := make([]map[string]dynamodb.AttributeValue, len(batch))
for j, id := range batch {
keys[j] = map[string]dynamodb.AttributeValue{
"id": {S: aws.String(id)},
}
}
req := svc.BatchGetItemRequest(&dynamodb.BatchGetItemInput{
RequestItems: map[string]dynamodb.KeysAndAttributes{
tableName: {Keys: keys},
},
})
resp, err := req.Send()
if err != nil {
return nil, err
}
allItems = append(allItems, resp.Responses[tableName]...)
// Handle unprocessed keys (throttling)
if len(resp.UnprocessedKeys) > 0 {
time.Sleep(100 * time.Millisecond)
// Retry unprocessed keys...
}
}
return allItems, nil
}import (
"encoding/json"
"github.com/aws/aws-sdk-go-v2/service/lambda"
)
type LambdaPayload struct {
Action string `json:"action"`
Data map[string]interface{} `json:"data"`
}
type LambdaResponse struct {
StatusCode int `json:"statusCode"`
Body string `json:"body"`
Headers map[string]string `json:"headers"`
}
func invokeLambdaSync(functionName string, payload LambdaPayload) (*LambdaResponse, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := lambda.New(cfg)
payloadBytes, _ := json.Marshal(payload)
req := svc.InvokeRequest(&lambda.InvokeInput{
FunctionName: aws.String(functionName),
Payload: payloadBytes,
InvocationType: lambda.InvocationTypeRequestResponse, // Sync
LogType: lambda.LogTypeTail, // Get logs in response
})
resp, err := req.Send()
if err != nil {
return nil, err
}
// Check function error
if resp.FunctionError != nil {
return nil, fmt.Errorf("lambda error: %s", *resp.FunctionError)
}
// Parse response
var result LambdaResponse
if err := json.Unmarshal(resp.Payload, &result); err != nil {
return nil, fmt.Errorf("response parse error: %w", err)
}
// Decode logs if present
if resp.LogResult != nil {
logBytes, _ := base64.StdEncoding.DecodeString(*resp.LogResult)
fmt.Printf("Lambda logs:\n%s\n", string(logBytes))
}
return &result, nil
}
// Async invocation
func invokeLambdaAsync(functionName string, payload LambdaPayload) error {
cfg, _ := external.LoadDefaultAWSConfig()
svc := lambda.New(cfg)
payloadBytes, _ := json.Marshal(payload)
req := svc.InvokeRequest(&lambda.InvokeInput{
FunctionName: aws.String(functionName),
Payload: payloadBytes,
InvocationType: lambda.InvocationTypeEvent, // Async - returns immediately
})
_, err := req.Send()
return err
}import "github.com/aws/aws-sdk-go-v2/service/ec2"
func listInstancesFiltered(filters map[string][]string) ([]*ec2.Instance, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := ec2.New(cfg)
// Build filter list
ec2Filters := []ec2.Filter{}
for name, values := range filters {
ec2Filters = append(ec2Filters, ec2.Filter{
Name: aws.String(name),
Values: values,
})
}
req := svc.DescribeInstancesRequest(&ec2.DescribeInstancesInput{
Filters: ec2Filters,
})
var instances []*ec2.Instance
p := req.Paginate()
for p.Next() {
page := p.CurrentPage().(*ec2.DescribeInstancesOutput)
for _, reservation := range page.Reservations {
instances = append(instances, reservation.Instances...)
}
}
if err := p.Err(); err != nil {
return nil, err
}
return instances, nil
}
// Example usage:
// instances, _ := listInstancesFiltered(map[string][]string{
// "instance-state-name": {"running"},
// "tag:Environment": {"production"},
// "instance-type": {"t3.micro", "t3.small"},
// })import (
"fmt"
"time"
"github.com/aws/aws-sdk-go-v2/service/sqs"
)
func processMessages(queueURL string, handler func(sqs.Message) error) error {
cfg, _ := external.LoadDefaultAWSConfig()
svc := sqs.New(cfg)
for {
// Receive messages
req := svc.ReceiveMessageRequest(&sqs.ReceiveMessageInput{
QueueUrl: aws.String(queueURL),
MaxNumberOfMessages: aws.Int64(10), // Max 10
WaitTimeSeconds: aws.Int64(20), // Long polling (0-20)
VisibilityTimeout: aws.Int64(30), // 30 seconds to process
MessageAttributeNames: []string{"All"},
AttributeNames: []sqs.QueueAttributeName{
sqs.QueueAttributeNameAll,
},
})
resp, err := req.Send()
if err != nil {
return err
}
if len(resp.Messages) == 0 {
continue // No messages, keep polling
}
// Process each message
for _, msg := range resp.Messages {
// Process message
if err := handler(msg); err != nil {
fmt.Printf("Failed to process message %s: %v\n", *msg.MessageId, err)
// Make visible again for retry
chgReq := svc.ChangeMessageVisibilityRequest(&sqs.ChangeMessageVisibilityInput{
QueueUrl: aws.String(queueURL),
ReceiptHandle: msg.ReceiptHandle,
VisibilityTimeout: aws.Int64(0), // Immediately visible
})
chgReq.Send()
continue
}
// Delete successfully processed message
delReq := svc.DeleteMessageRequest(&sqs.DeleteMessageInput{
QueueUrl: aws.String(queueURL),
ReceiptHandle: msg.ReceiptHandle,
})
if _, err := delReq.Send(); err != nil {
fmt.Printf("Failed to delete message: %v\n", err)
}
}
}
}import "github.com/aws/aws-sdk-go-v2/service/sns"
func publishWithAttributes(topicARN, message string, attributes map[string]string) error {
cfg, _ := external.LoadDefaultAWSConfig()
svc := sns.New(cfg)
// Build message attributes
msgAttrs := make(map[string]sns.MessageAttributeValue)
for key, val := range attributes {
msgAttrs[key] = sns.MessageAttributeValue{
DataType: aws.String("String"),
StringValue: aws.String(val),
}
}
// Add numeric attribute
msgAttrs["timestamp"] = sns.MessageAttributeValue{
DataType: aws.String("Number"),
StringValue: aws.String(fmt.Sprintf("%d", time.Now().Unix())),
}
req := svc.PublishRequest(&sns.PublishInput{
TopicArn: aws.String(topicARN),
Message: aws.String(message),
MessageAttributes: msgAttrs,
// Optional: Subject, MessageStructure (for mobile push)
})
resp, err := req.Send()
if err != nil {
return err
}
fmt.Printf("Published: MessageID=%s\n", *resp.MessageId)
return nil
}import "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
func tailLogs(logGroup, logStream string) error {
cfg, _ := external.LoadDefaultAWSConfig()
svc := cloudwatchlogs.New(cfg)
var nextToken *string
for {
req := svc.GetLogEventsRequest(&cloudwatchlogs.GetLogEventsInput{
LogGroupName: aws.String(logGroup),
LogStreamName: aws.String(logStream),
NextToken: nextToken,
StartFromHead: aws.Bool(true),
Limit: aws.Int64(100),
})
resp, err := req.Send()
if err != nil {
return err
}
// Print events
for _, event := range resp.Events {
ts := time.Unix(*event.Timestamp/1000, 0)
fmt.Printf("[%s] %s\n", ts.Format(time.RFC3339), *event.Message)
}
// Check if done
if resp.NextForwardToken == nil ||
(nextToken != nil && *resp.NextForwardToken == *nextToken) {
break // No more events
}
nextToken = resp.NextForwardToken
time.Sleep(1 * time.Second) // Rate limiting
}
return nil
}import "github.com/aws/aws-sdk-go-v2/service/sts"
func assumeRole(roleARN, sessionName string) (aws.Config, error) {
cfg, _ := external.LoadDefaultAWSConfig()
stsSvc := sts.New(cfg)
req := stsSvc.AssumeRoleRequest(&sts.AssumeRoleInput{
RoleArn: aws.String(roleARN),
RoleSessionName: aws.String(sessionName),
DurationSeconds: aws.Int64(3600), // 1 hour
// Optional: ExternalId, Policy, Tags
})
resp, err := req.Send()
if err != nil {
return cfg, err
}
// Create new config with assumed role credentials
assumedConfig := cfg.Copy()
assumedConfig.Credentials = aws.NewStaticCredentialsProvider(
*resp.Credentials.AccessKeyId,
*resp.Credentials.SecretAccessKey,
*resp.Credentials.SessionToken,
)
return assumedConfig, nil
}// WRONG - panics if field is nil
name := *resp.User.Name
// CORRECT - check before dereferencing
if resp.User != nil && resp.User.Name != nil {
name := *resp.User.Name
}
// BEST - use helper (returns empty string if nil)
name := aws.StringValue(resp.User.Name)// Nil slice - field omitted from request
Tags: nil
// Empty slice - field sent as empty array []
Tags: []ec2.Tag{}
// For required fields, use empty slice if no values:
Filters: []ec2.Filter{} // Better than nil for required fields// Arguments come as interface{} - must type assert
id := p.Args["id"].(string) // Panics if wrong type
limit := p.Args["limit"].(int) // Panics if wrong type
// Safe assertions:
id, ok := p.Args["id"].(string)
if !ok {
return nil, fmt.Errorf("id must be string")
}
// Handle optional arguments:
limit := 10 // default
if val, ok := p.Args["limit"]; ok {
if limitInt, ok := val.(int); ok {
limit = limitInt
}
}ctx, cancel := context.WithCancel(context.Background())
// Cancel from another goroutine
go func() {
time.Sleep(5 * time.Second)
cancel()
}()
req := svc.GetObjectRequest(input)
req.SetContext(ctx)
_, err := req.Send()
if err == context.Canceled {
// Request was cancelled
}
if err == context.DeadlineExceeded {
// Request timed out
}// Empty results
p := req.Paginate()
hasResults := false
for p.Next() {
hasResults = true
// Process page
}
if !hasResults {
if err := p.Err(); err != nil {
// Error occurred
return err
}
// No results (not an error)
}
// Always check p.Err() after loop
for p.Next() {
// Process
}
if err := p.Err(); err != nil {
// Pagination failed mid-stream
return err
}import "sync"
// Requests are NOT thread-safe - create per-goroutine
func concurrentUploads(bucket string, files []string) error {
cfg, _ := external.LoadDefaultAWSConfig()
svc := s3.New(cfg) // Service client IS thread-safe
var wg sync.WaitGroup
errChan := make(chan error, len(files))
for _, file := range files {
wg.Add(1)
go func(f string) {
defer wg.Done()
// Create NEW request per goroutine
req := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(f),
// ... upload file
})
if _, err := req.Send(); err != nil {
errChan <- err
}
}(file)
}
wg.Wait()
close(errChan)
// Check for errors
for err := range errChan {
return err
}
return nil
}import "net/http"
cfg, _ := external.LoadDefaultAWSConfig()
cfg.HTTPClient = &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
MaxConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
},
}cfg.EndpointResolver = aws.EndpointResolverFunc(
func(service, region string) (aws.Endpoint, error) {
if service == "s3" {
return aws.Endpoint{
URL: "http://localhost:4566", // LocalStack
SigningRegion: region,
Source: aws.EndpointSourceCustom,
}, nil
}
if service == "dynamodb" {
return aws.Endpoint{
URL: "http://localhost:8000", // DynamoDB Local
SigningRegion: region,
}, nil
}
// Use default for other services
return aws.Endpoint{}, fmt.Errorf("unknown endpoint")
},
)import "github.com/aws/aws-sdk-go-v2/aws/retry"
cfg.Retryer = retry.NewStandard(func(s *retry.Standard) {
s.MaxAttempts = 5
s.MaxBackoff = 30 * time.Second
})cfg.LogLevel = aws.LogDebugWithHTTPBody // Verbose logging
cfg.Logger = aws.NewDefaultLogger()
// Custom logger
cfg.Logger = aws.LoggerFunc(func(classification ...interface{}) {
fmt.Println(classification...)
})// Define interface for testing
type S3API interface {
GetObjectRequest(*s3.GetObjectInput) s3.GetObjectRequest
PutObjectRequest(*s3.PutObjectInput) s3.PutObjectRequest
}
// Function accepts interface
func downloadFile(svc S3API, bucket, key string) error {
req := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
resp, err := req.Send()
// ...
}
// In tests, implement interface with mockfunc newLocalStackConfig() aws.Config {
cfg := aws.NewConfig()
cfg.Region = "us-east-1"
cfg.Credentials = aws.NewStaticCredentialsProvider("test", "test", "")
cfg.EndpointResolver = aws.EndpointResolverFunc(
func(service, region string) (aws.Endpoint, error) {
return aws.Endpoint{
URL: "http://localhost:4566",
SigningRegion: region,
}, nil
},
)
// Disable SSL verification for local testing
cfg.HTTPClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
return *cfg
}// Reuse service clients - they manage connection pooling
var s3Client *s3.S3
func init() {
cfg, _ := external.LoadDefaultAWSConfig()
s3Client = s3.New(cfg)
}
// Use s3Client in multiple functions// Use batch operations when available
// Instead of:
for _, id := range ids {
svc.DeleteObjectRequest(&s3.DeleteObjectInput{...}).Send()
}
// Do this:
objects := make([]s3.ObjectIdentifier, len(ids))
for i, id := range ids {
objects[i] = s3.ObjectIdentifier{Key: aws.String(id)}
}
svc.DeleteObjectsRequest(&s3.DeleteObjectsInput{
Bucket: aws.String(bucket),
Delete: &s3.Delete{Objects: objects},
}).Send()var cache = make(map[string]*s3.GetObjectOutput)
var cacheMu sync.RWMutex
func getCached(bucket, key string) (*s3.GetObjectOutput, error) {
cacheKey := bucket + "/" + key
cacheMu.RLock()
if cached, ok := cache[cacheKey]; ok {
cacheMu.RUnlock()
return cached, nil
}
cacheMu.RUnlock()
// Fetch from S3
resp, err := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
}).Send()
if err != nil {
return nil, err
}
cacheMu.Lock()
cache[cacheKey] = resp
cacheMu.Unlock()
return resp, nil
}func uploadWithBackoff(bucket, key string, body io.Reader) error {
cfg, _ := external.LoadDefaultAWSConfig()
svc := s3.New(cfg)
maxRetries := 5
baseDelay := 100 * time.Millisecond
for attempt := 0; attempt < maxRetries; attempt++ {
req := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Body: body,
})
_, err := req.Send()
if err == nil {
return nil // Success
}
if aerr, ok := err.(awserr.Error); ok {
if aerr.Code() == "SlowDown" || aerr.Code() == "ServiceUnavailable" {
// Exponential backoff
delay := baseDelay * time.Duration(1<<uint(attempt))
time.Sleep(delay)
continue
}
}
return err // Non-retryable error
}
return fmt.Errorf("max retries exceeded")
}func objectExists(bucket, key string) (bool, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := s3.New(cfg)
req := svc.HeadObjectRequest(&s3.HeadObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
_, err := req.Send()
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
if aerr.Code() == s3.ErrCodeNoSuchKey || aerr.Code() == "NotFound" {
return false, nil // Object doesn't exist (not an error)
}
}
return false, err // Real error
}
return true, nil // Object exists
}// For large list operations, always paginate
func listAllObjects(bucket string) ([]string, error) {
cfg, _ := external.LoadDefaultAWSConfig()
svc := s3.New(cfg)
var keys []string
req := svc.ListObjectsV2Request(&s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
MaxKeys: aws.Int64(1000), // Max per page
})
p := req.Paginate()
for p.Next() {
page := p.CurrentPage().(*s3.ListObjectsV2Output)
for _, obj := range page.Contents {
keys = append(keys, *obj.Key)
}
// Optional: Add delay to avoid throttling
if page.IsTruncated != nil && *page.IsTruncated {
time.Sleep(100 * time.Millisecond)
}
}
return keys, p.Err()
}// String attribute
attr := dynamodb.AttributeValue{S: aws.String("value")}
// Number attribute (stored as string)
attr := dynamodb.AttributeValue{N: aws.String("123")}
attr := dynamodb.AttributeValue{N: aws.String("123.45")}
// Boolean attribute
attr := dynamodb.AttributeValue{BOOL: aws.Bool(true)}
// Binary attribute
attr := dynamodb.AttributeValue{B: []byte("binary data")}
// Null attribute
attr := dynamodb.AttributeValue{NULL: aws.Bool(true)}
// List attribute
attr := dynamodb.AttributeValue{
L: []dynamodb.AttributeValue{
{S: aws.String("item1")},
{S: aws.String("item2")},
},
}
// Map attribute
attr := dynamodb.AttributeValue{
M: map[string]dynamodb.AttributeValue{
"nested": {S: aws.String("value")},
"count": {N: aws.String("10")},
},
}
// String set
attr := dynamodb.AttributeValue{SS: []string{"a", "b", "c"}}
// Number set
attr := dynamodb.AttributeValue{NS: []string{"1", "2", "3"}}// Modify request before sending
req := svc.GetObjectRequest(input)
// Add custom headers
req.HTTPRequest.Header.Set("X-Custom-Header", "value")
// Modify using handlers
req.Handlers.Send.PushFront(func(r *aws.Request) {
// Called before HTTP request sent
fmt.Printf("Sending request to: %s\n", r.HTTPRequest.URL)
})
req.Handlers.Complete.PushBack(func(r *aws.Request) {
// Called after request completes
fmt.Printf("Request completed with status: %d\n", r.HTTPResponse.StatusCode)
})
_, err := req.Send()For more patterns and complete API reference, see reference documentation.
Install with Tessl CLI
npx tessl i tessl/golang-github-com--aws--aws-sdk-go-v2@0.4.0