Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

json annotations are not supported in attributevalue.MarshalMap #1486

Closed
3 tasks done
Cyberax opened this issue Nov 8, 2021 · 8 comments
Closed
3 tasks done

json annotations are not supported in attributevalue.MarshalMap #1486

Cyberax opened this issue Nov 8, 2021 · 8 comments
Labels
feature-request A feature should be added or improved.

Comments

@Cyberax
Copy link
Contributor

Cyberax commented Nov 8, 2021

Confirm by changing [ ] to [x] below to ensure that it's a bug:

Describe the bug
json annotations are not supported in attributevalue.MarshalMap. The only supported annotations are dynamodbav. This is a regression compared to the V1 SDK.

Version of AWS SDK for Go?
Example: v1.11.0, DDB: 1.7.0

Version of Go (go version)?
1.16

To Reproduce (observed behavior)

type SomeStruct struct{
    Id string `json:"id"`
}
s := SomeStruct{Id: "123"}
values, err := attributevalue.MarshalMap(&s)
// values will contain: {Id -> "123"} - note the upper case

Expected behavior
Return:

id -> "123"
@Cyberax Cyberax added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Nov 8, 2021
@moogacs
Copy link

moogacs commented Dec 2, 2021

I have encountered the same bug which json tag is not respected when marshalling a struct and it has inconsistent behaviour that it's sometimes respected and sometimes not

go version v1.16
dynamodb v1.9.0 
aws sdk v1.11.1

@0DegreesKelvin
Copy link

Same bug for me after update to aws sdk v1.11.1

@jasdel
Copy link
Contributor

jasdel commented Dec 3, 2021

Thanks for reaching out. The issue you're experiencing is the intended behavior of V2 SDK's AttributeValue (un)marshalers. The best way to configure the (un)marshalers to use alternative struct tags is to documented in the package's Overview

There are a few ways you can configure the (un)marshaler for the serialized id to use.

  • add dynamodbav:"name" struct tag to fields
  • Implement attributevalue.Marshaler with custom specification of conversion between Go type and AttributeValue.
  • Specify EncoderOptions or DecoderOptions when creating an encoder specifying the struct tag that should be used for names.

@jasdel jasdel added feature-request A feature should be added or improved. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Dec 3, 2021
@jasdel
Copy link
Contributor

jasdel commented Dec 3, 2021

Issue, #1494 and PR #1495 help address the overall issue of configuring the (un)marshaler with alternative tagkeys.

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Dec 4, 2021
@moogacs
Copy link

moogacs commented Dec 6, 2021

Thanks for your response @jasdel, I know those solutions and that what I am doing at the moment but
that is not what AWS documentation and source code says

// Tag key `dynamodbav` will always be read, but if custom tag key
// conflicts with `dynamodbav` the custom tag key value will be used.
TagKey string
type EncoderOptions struct {
	// Support other custom struct tag keys, such as `yaml`, `json`, or `toml`.
	// Note that values provided with a custom TagKey must also be supported
	// by the (un)marshalers in this package.
	//
	// Tag key `dynamodbav` will always be read, but if custom tag key
	// conflicts with `dynamodbav` the custom tag key value will be used.
	TagKey string

	// Will encode any slice being encoded as a set (SS, NS, and BS) as a NULL
	// AttributeValue if the slice is not nil, but is empty but contains no
	// elements.
	//
	// If a type implements the Marshal interface, and returns empty set
	// slices, this option will not modify the returned value.
	//
	// Defaults to enabled, because AttributeValue sets cannot currently be
	// empty lists.
	NullEmptySets bool
}

and the behaviour is inconsistent because, some times it marshals the structs correctly and sometimes not and that causes a lot of inconsistency in the databases

@moogacs
Copy link

moogacs commented Dec 6, 2021

@jasdel To proof what we are talking about, here a demonstration of different behaviours for the same pkg

case 1 :
IDLE case expected behavior using custom marshaler
https://go.dev/play/p/zoqHVu5tVjN

case 2 :
2 go routines do the same thing but one of them using custom tag marshaler and other is not and they lead to the same results
https://go.dev/play/p/HvpkhgDUl63

case 3 :
simply case 2 without go routines and it seems the custom tag marshaler doesn't work and affected by the other one
https://go.dev/play/p/ruZGAaWAgtx

all what you need to look at the printed keys Data and UserID

@jasdel
Copy link
Contributor

jasdel commented Jan 21, 2022

I've created #1569 to track the issue with the SDK's DDB attribute value marshaler inconsistently serializing struct field names. Lets track that issue, and close this one. since this issue focused on the original feature to provide options to attributivevalue's (un)marshalers for TagKeys.

@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved.
Projects
None yet
Development

No branches or pull requests

4 participants