S3

S3 - Bucketlister

Bucketlister example

To have a real-world-example we split them main function as consumer from the function from the module listbuckets.

As this is the first SDK example I’ll try to explain in detail.

This way its easy to reuse the module elsewhere. To keep it simple, we do not use an extra interface like in aws listbucket example.

sequenceDiagram participant main participant listbuckets participant s3 main->>listbuckets: ListBuckets listbuckets ->> listbuckets: init - initialize client listbuckets ->> s3: ListBuckets listbuckets ->> listbuckets: fill slice with range listbuckets ->> main: array of bucketnames

Steps

  1. Init Module
  2. Import config and service S3
  3. Init a configuration
  4. create a client
  5. initialize parameter
  6. call service
  7. handle error
  8. read results

0 - Init module

If you start with an empty directory you:

  • Init the module `go mod init listbuckets``
  • Create a main directory mkdir main

and create at least two files:

main/main.go

package main
import (
	"listbuckets"
)
func main(){
	// fill with code
}

This file imports the module listbucket, so it can use the exported functions.

lister.go

package listbuckets
import (

)
func ListBuckets() ([]*string, error){

	return bucketarray, nil

}

1 - Import config and service S3

import (
	"context"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

To use any AWS service, you need the config and the service import. The contextcan be useful to “carry values across API boundaries and between processes” (See package doc).

Usually you just use context.TODO() and forget about it.

2 - Init a configuration

If you need to use the S3 client in multiple functions in the package, you may init the client in the init function, which is called when the module is initalized. Be careful if you use multiple inits in a module, because the call order is somehow tricky. If you stick with one init, live is easier.

3. Create a client

Now we declare the client package wide and initialize it in init:

var client *s3.Client

func init(){
	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		panic("configuration error, " + err.Error())
	}
	client = s3.NewFromConfig(cfg)
}

This way we can just use the client and can be sure that it is initalized.

4. Initialize parameter

To call any GO function we have to fill the parameter.

The ListBucketsInput is always empty, so you init it empty.

&s3.ListBucketsInput{}

FunFact: at the moment you may see “noSmithyDocumentSerde” in the documentation of the ListBucketsInput. This comes from the fact, that large parts of the GO SDK V2 are generated out of AWS Smithy

5. Call service

res, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})

The services return not only the result, which is named apicall Output (ListBucketsOutput here), but also an error.

6. Handle error

Its up to you where you log the error, but you should log it. In this example we just give the error back.

	if err != nil {
		return nil, err
	}

7. Read Results

Now we read the results and fill a slice to return it:

	for _, bucket := range res.Buckets {
		bucketarray = append(bucketarray, bucket.Name)
	}

	return bucketarray, nil

See also

Source

See the full source on github.

Sources