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

proposal: encoding/json: support struct tag for time.Format in JSON Marshaller/Unmarshaller #21990

Open
marwan-at-work opened this Issue Sep 23, 2017 · 2 comments

Comments

Projects
None yet
4 participants
@marwan-at-work
Contributor

marwan-at-work commented Sep 23, 2017

I will start with the proposal as a TL;DR before explaining the motivations behind it:

Proposal

It would be quite convenient if we could have the encoding/json package understand the format of time.Time as part of the struct definition. Something like this:

type User struct {
	Name     string
	JoinDate time.Time `time:"2006-01-02"`
}

This means that when you write json.Unmarshal(data, &user), the json package will understand what format to parse/serialize the field with.

Motivation/Experience Report

Currently, there are three workarounds:

  1. type MyTime time.Time: https://goplay.space/#APZL4Rzlm_

  2. Embedding time.Time in MyTime type: https://goplay.space/#q-oKnSTtQV

  3. Implementing json.Unmarshaller on the parent struct: https://goplay.space/#mzb8MQfajl

Those workarounds are not bad. However, I've noticed that they get out of hand once your codebase starts to scale.

Imagine having hundreds of structs with hundreds of fields where many of them could have different Time types just because they have different serialization formats, and nothing else.

The time.Time package, I think, might be too opinionated to assume RFC3339 is the only acceptable format in the json.Unmarshaller interface: https://github.com/golang/go/blob/master/src/time/time.go#L1232. (Same goes for RFC3339Nano in the json.Marshaller implementation).

I think it makes sense for it to be a default serialization format, but not the only one. The workaround is initially not bad at all. However, it gets cumbersome when your project scales.

I think this proposal shows that the above solution can make our code more declarative and less cumbersome. This echo's Rob Pike's talk in that here we can hide complexity behind a simple interface.

Lastly, this doesn't make or break my Go experience, but I personally see room for enhancement here.

@ianlancetaylor ianlancetaylor changed the title from Include Struct Tag for time.Format in JSON Marshaller/Unmarshaller to encoding/json: support struct tag for time.Format in JSON Marshaller/Unmarshaller Sep 24, 2017

@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Sep 24, 2017

@rsc

This comment has been minimized.

Contributor

rsc commented Oct 23, 2017

It's an interesting idea and maybe one to consider the next time we take a chunk of json decisions to make. For now the usual idiom is the wrapper type, as you described. Going to mark this as a proposal-hold for whenever the next rethink of json is.

@gnodiah

This comment has been minimized.

gnodiah commented Jul 27, 2018

up!

That would be convenient if it can specify time format through json tag, because formatting time is a more often behavior in most cases.

@dsnet dsnet changed the title from encoding/json: support struct tag for time.Format in JSON Marshaller/Unmarshaller to proposal: encoding/json: support struct tag for time.Format in JSON Marshaller/Unmarshaller Sep 22, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment