How to call the Values function in aws-sdk-go-v2?

0

I originally asked this question on StackOverflow but never received any reply. No one from AWS seems to be monitoring aws-sdk-go questions on StackOverflow. So I want to try again here. It would be great if more AWS employees could monitor re:Post and answer SDK questions.

I am writing a program that uses aws-sdk-go-v2 and receives a string input from the user that determines what storage class to use when storing an object in S3. I have to validate that the input is an allowed value, and if it is not, I give a list of allowed values.

In v1 of aws-sdk-go, you could call s3.StorageClass_Values() to enumerate the allowed StorageClass values.

func StorageClass_Values() []string

Example:

// v1.go
package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/service/s3"
)

func main() {
	fmt.Println(s3.StorageClass_Values())
}
$ go run v1.go
[STANDARD REDUCED_REDUNDANCY STANDARD_IA ONEZONE_IA INTELLIGENT_TIERING GLACIER DEEP_ARCHIVE OUTPOSTS]

But in aws-sdk-go-v2, types were introduced for StorageClass and the function that enumerates the values requires a type to be called.

From the docs:

func (StorageClass) Values() []StorageClass

This seems to require an initialized variable to call? Why is this the case? What's the idiomatic way to call this function?

I've managed to get it to work in two different ways, and both seem wrong.

// v2.go
package main

import (
	"fmt"

	s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types"
)

func main() {
	// Create uninitialized StorageClass variable and call .Values()
	var sc s3Types.StorageClass
	fmt.Println(sc.Values())

	// One-liner that uses one of the types directly:
	fmt.Println(s3Types.StorageClassStandard.Values())
}
$ go run v2.go
[STANDARD REDUCED_REDUNDANCY STANDARD_IA ONEZONE_IA INTELLIGENT_TIERING GLACIER DEEP_ARCHIVE OUTPOSTS]
[STANDARD REDUCED_REDUNDANCY STANDARD_IA ONEZONE_IA INTELLIGENT_TIERING GLACIER DEEP_ARCHIVE OUTPOSTS]

The one-liner is better because it is more concise, but I have to reference one of the storage classes, which doesn't have a particular meaning, so it feels wrong.

Which one should I use and why?

I wish they had simply kept the calling convention from v1. The Values() function in v2 doesn't use the type sent to it.

asked a year ago166 views
1 Answer
2

Hi, V2 of the SDK now provides a typed experience for all API enumeration fields. Rather than using a string literal value copied from the service API reference documentation, you can now use one of the concrete types found in the service client’s types package. The types package provides generated constants for the valid enumeration values that can be used for assignment or conditional testing whereas with V1 you needed to use string literals. So this allows better type checking and I think improves readability.

I'm by no means a Go expert, but I agree that s3Types.StorageClassStandard.Values() feels a bit weird. In V2, Values() expects a receiver of type StorageClass so calling (StorageClass).Values() doesn't work in Go as StorageClass is a type, not an "instance" of a type, and this also doesn't work as it would in C because Go doesn't support 'static' class methods like C does.

Since Values() is expecting a receiver of type StorageClass, you could actually pass any of the StorageClass types. I don't know I would recommend it, but since StorageType is of type string, you could also use:

 s3Types.StorageClass("").Values() 

or

const storageClass = s3Types.StorageClass("")
...
fmt.Println(storageClass.Values())
Scott_K
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions