Don't generate central unmarshal/marshal method more than once per package. Simply check file existence?
Key generation and utility
We would like to generate some way to generate Dynamo key helper methods. Carefull key construction in DynamoDB
is important because it directly determines how data can be queried effiently. It is unlikely that
we can capture this logic in Protobuf. Some ideas
Allow certain fields to be involved in the key generation, then generate a method/function that takes
a lambda and should output the key(s)
It will also error if the fields are not set before this is called
PK/SK are often values stringed together for example with "#"
Parts of the PK/SK can be constants, maybe allow enums to be used?
Parts of the PK/SK can be constant given the message type
Would be nice if these pk/sk constructions are flagged when changed in a backwards incompatible way
Could generate functions that create key attribute maps
What should the helping do for the various methods
GetItem, UpdateItem, DeleteItem: turn basic Go type (string, int), passed in a request parameters into a
attribute map with just the key values
PutItem: should produce a full item, including keys into a dynamodb attribute map
QueryItem: should produce a exact partition key, and variety of expressions on the sort key
Minimal Viable Backlog
MUST generate methods that return PartitionKey (name/value), and SortKey (name/value)
MUST deploy a buf module so users can easily include options
Documentation backlog
Write the rules for what kind of fields can be set as a PK, or SK
Write what well-known types encode to what
Feature Backlog
SHOULD add field option to support (un)marshalling StringSets, NumberSets, ByteSets etc
SHOULD allow skipping certain fields for all dynamodb marshalling/unmarshalling: ignore option
SHOULD support encoding compex types (messages, maps, strucpb, oneof values as json AND/OR binary protobuf)
COULD generate query building structure for FilterExpressions/KeyConditionExpressions etc
COULD add errors to the "MarshalDynamoKey" method if range/sort key is empty string, or empty bytes (0 number is fine?)
COULD generate var/consts that return the attribute name for a member, so it can be used in DynamoExpressions
, so instead of attribute_not_exists(pk) it can be attribute_not_exists("+modelv1.ProfileSortKey+") - Should generates methods that returns the SortKey() and PartitionKey() so interfaces can be defined
for helper methods
COULD (if we have annotations on what are the keys), to implement a GetItem implementation that fetches
the rest of the item from the database.
COULD add option to "skip unsupported" instead of error (but why not just "ignore" the field?)
COULD make it configurable on how to handle nil/empty fields like stdlib json package
COULD support pk/sk options for fields that are message types, as long as the message has textencoding interface of some sort
COULD allow customizing the encoder/decoder options
make sure that logic applies to both marshalling, and unmarshalling (new test case)
COULD improve usability of FieldMask encoding, instead of slice of strings of the field names in
proto definition, could/should be the dynamodb attribute names. But this probably means implement another version of the fieldmaskpb.New() function. But https://pkg.go.dev/google.golang.org/protobuf/types/known/fieldmaskpb#Intersect states that "field.number" paths are also valid
Hardening Backlog
SHOULD test boolean key maps
SHOULD fix go vet checks failure
SHOULD Add test that errors when unsupported map type is used
SHOULD Fuzz the "FieldPresence" message as well, but this might require revamping the fuzzing setup because
of interface types in the generated types
SHOULD test that messages from external packages that DO implement the MarshalDynamoItem can be used
in fields without problem
SHOULD turn panics into errors (or add catch mechanism)
COULD fuzz using official go toolchain fuzzing
Done Backlog
SHOULD add method that marshals just the keys (if any keys are configured), fail if more keys, fail if no data in keys
SHOULD add code generation that adds methods to return the PartitionKey and SortKey from a message
SHOULD run test with parralel and -race enabled
MUST add file header that states that the file is generated
SHOULD test support of wrapper types (what about optional field with wrapper types?)
SHOULD add a test that passes in empty (or half empty) attribute maps into unmarshal and unmarshalled struct
to match what would be marshalled from from json.
SHOULD match output field presence to that of json encoding
SHOULD test with OneOf field
SHOULD Make sure generated error handling prints the field name and a more descriptive error
SHOULD allow customizing the dynamodb attribute name (from default "field number")
SHOULD error when marshalling map of messages and the key is an empty string (not allowed)
SHOULD get a good grip on "Nullability" of fields, the documentation for "WrapperTypes" suggests that: "Wrappers use the same representation in JSON as the wrapped primitive type, except that null is allowed and preserved during data conversion and transfer.". Which suggests that
null values are normally not preserved. So fields have "nil"value when marschalling (or the zero) value of
a message should not have any "null" attributes.
When generating JSON-encoded output from a protocol buffer, if a protobuf field has the default value and if the field doesn’t support field presence, it will be omitted from the output by default. An implementation may provide options to include fields with default values in the output.
A proto3 field that is defined with the optional keyword supports field presence. Fields that have a value set and that support field presence always include the field value in the JSON-encoded output, even if it is the default value.