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

suggestion: Refactor Library Encoder/Decoder to use github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute #28

Closed
tamccall opened this issue Apr 3, 2017 · 4 comments

Comments

@tamccall
Copy link
Contributor

tamccall commented Apr 3, 2017

Aws sdk has their own implementation of the struct tags contained in this library suggest refactoring this library to make use of their struct tags to stay more inline with the official release

See:
https://godoc.org/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute

@tamccall tamccall changed the title suggestion: Refactor Library Encoder/Decoder to use suggestion: Refactor Library Encoder/Decoder to use github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute Apr 3, 2017
@mattatcha
Copy link

@KingofSouth I currently have a fork which I am refactoring to use dynamodbattribute. I plan on submitting a PR when it is finished.

https://github.com/mattaitchison/dynamo

@guregu
Copy link
Owner

guregu commented Apr 5, 2017

I think it's a great idea to support the official dynamodbav struct tags.

The reason this library has a custom implementation is because that package simply didn't exist when I made this. There was no other way to easily (un)marshal DynamoDB AV stuff. Later they added an extremely limited version, essentially a thin wrapper around json.Marshal along with its weird inconsistencies, providing no way to add sets, turning []byte into string instead of binary typed values, etc., so I stopped paying attention to it. I hadn't looked at until now but it seems like they've addressed most of those shortcomings. I need to take a closer look but looking at the tests in @MattAitchison's fork it seems like it's basically equivalent, which is great. Thank you for putting in the work.

This library might have some philosophical differences compared to the official one, though. For example, you cannot set a DynamoDB attribute to an empty string. It'll give you an error if you try. Empty strings are super common in Go so this library automatically omits them instead of erroring out. There are a number of types where this library will automatically omit them instead of producing invalid input. Ultimately they are arbitrary decisions I made a long time ago to help me avoid common mistakes.
On the other hand, the official library has its own arbitrary decisions on how to avoid invalid encodings. It will turn an empty string into null:true by default. This "poisons" your data with columns that can either be of the type null or the type string. It's much easier, IMO, to omit it and use the attribute_exists() functions rather than a kludgy type comparison. I'm not sure how it handles other invalid encodings. It also seems we have different ideas of what 'empty' should mean and they have a confusingly separate omitempty for certain types. I think the official package's decisions are a lot less arbitrary than mine, but this package was intended to be more like an opinionated ORM than an ultra-neutral do-anything encoder.

I think our options are:

  • support both encodings in this library, either via options or via reflection
  • maintain a more 'modern' fork that uses the AWS encodings only. You have a good opportunity to update the methods to refer to hash keys as partition keys and what not. There's a lot of things that could be improved.

Apologies for the wall of text, but I hope it helps explain why I'm not immediately pulling the plug on all of my crappy encoding code. There's a lot of real world software I don't want to break by suddenly dropping support for the dynamo tag, but I am interested in supporting the official way to marshal things. Keep in mind this library is over 2 years old, made back when the AWS libraries were unstable and breaking all the time. I've tried to keep breakages in this library over time relatively minor compared to it (despite the scary warning in the README).

@tamccall
Copy link
Contributor Author

tamccall commented Apr 5, 2017

one other thought that I had thought about encoding that I have had on this library is to add a Marshaller interface that the table uses basically it would define:

These to methods in the interface:

Then you could have two implementations of that interface one with all of the marshaling code that exists and one that uses the aws default.

Would also allow clients to make a single marshaller for handling things like for instance encryption and use it with every struct that they persist. That way every struct in the package doesn't have some boilerplate MarshalDynamo method.

Just an idea for a potential alternate approach

@guregu
Copy link
Owner

guregu commented Jun 8, 2017

@tamccall I've implemented something like your idea in #34! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants