aws-sdk-go-v2 icon indicating copy to clipboard operation
aws-sdk-go-v2 copied to clipboard

Add support for omitting attribute values returned by custom Marshaler implementations

Open lmika opened this issue 3 years ago • 0 comments

Is your feature request related to a problem? Please describe.

We are working on a project that uses a custom type to represent UUIDs. This type, which extends github.com/google/uuid, stores the UUID in memory as a [16]byte array, but we’ve added a custom Marshal and Unmarshal implementation that marshals/unmarshals it to a string UUID representation.

We were hoping to allow the service writing rows to the DynamoDB table to omit an id field when the UUID is nil (i.e. 16 zero bytes). However, we’ve discovered that this is not possible to do when using a type that implements github.com/aws/aws-sdk-go-v2/service/dynamodb/dynamodbattribute.Marshaler. We’re hoping that this could be added in some way.

Describe the solution you'd like

There’s not a huge preference as to how this is implemented, either the following suggestion or one of the alternatives will be find. Depending on the stability of the API, an ideal solution would be to return double nil from Marshal.MarshalDynamoDBAttributeValue to indicate that no attribute value should be marshalled out. Example:

func (u UUID) MarshalDynamoDBAttributeValue() (types.AttributeValue, error) {
	if u == NilUUID {
		// Indicate that no value should be stored for this attribute.
		return nil, nil
	}

	return &types.AttributeValueMemberS{
		Value: u.String(),
	}, nil
}

Describe alternatives you've considered

A few other suggestions for this approach:

  • Add support for omitempty in the struct tag for custom types. So using the example above, if u is NilUUID, then the function will return a types.AttributeValueMemberS with an empty string. Since the field that has this type also has the omitempty option in the struct tag, the value won’t be marshalled out to the database.
  • Either a dedicated attribute type or error type that acts as a sentinal would also work.

Additional context

We’re using “aws-sdk-go-v2” version 1.5.0 with Go 1.16.6

lmika avatar Sep 20 '21 23:09 lmika