googleapis / googleapis/google-cloud-go

datastore: API for custom property-types

Open
#3,090 1 comment 0 reactions 0 assignees View on GitHub
api: datastore type: feature request
Dominant language
Go
Stars
4.5k
Forks
1.6k
Avg merge
1d 13h
Merged PRs (30d)
109

Description

**Is your feature request related to a problem? Please describe.**
The datastore package has a great API for custom loading/saving at the model level. This is great if you want to set things up specially for a particular model. But sometimes we have a common need, where we have some type of data that datastore doesn't natively represent (or that the Go library doesn't natively support) that we want to marshal in a standard, custom way. We can do that, but we have to write load/save methods, then have every model implement a Load/Save method which calls out to LoadStruct/SaveStruct, and then the special method, for each such property.

**Describe the solution you'd like**
The API I'm thinking would be something like:
```
// CustomProperty represents any type that can be marshalled or unmarshalled to a datastore Property. Datastore model-structs can include this as a field, just like any of the ordinary supported types.
type CustomProperty interface {
// Load updates the receiver in-place to have the value corresponding to the given value (which will be one of the types listed in the package documentation), or returns an error if that is not possible
Load(interface{}) error
// Save returns the value (of one of the types listed in the package documentation) corresponding to the receiver's current value, or returns an error if that is not possible.
Save() (interface{}, error)
}
```

I haven't thought these method signatures through super carefully (e.g. they could accept/return `datastore.Property` and the library would use `Name`/`NoIndex` as defaults), so I'm very open to alternatives.

If I were to have a pony, these methods would also accept a context (see #1718) :-) . But that might make this harder to integrate with `LoadStruct`/`SaveStruct`.

**Describe alternatives you've considered**
We could continue to implement custom PropertyLoadSaver methods for each one. This is a bit annoying -- one basically also has to reimplement the datastore tag handling logic, or make the methods hardcode a bunch of property-names.

In practice what we've done is to implement a custom wrapper for LoadStruct and SaveStruct that handles all of our custom properties. This works well enough for us, but means those are sort of all-or-nothing rather than a bunch of specific types one could pull in individually. It also means it's much harder to add support for new types -- e.g. I would love to see people on our team write custom types that make sense for their application code, but that's a bunch of extra work. (And such types are harder to open-source.)

**Additional context**
Having this be more customizable in user-land could also avoid feature requests for specific properties. If you can't tell, this idea came out of #3089, which if this is implemented we could easily write in userland (as a custom `Date` type, which could use `civil.Date` or any other implementation). One could also solve #916 (otherwise unsolvable without breaking compat) by writing a custom type wrapping `time.Time`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.