Usman Ismail
Usman Ismail

Reputation: 18679

How to tag a struct in go such that it reads values from JSON but does not write them?

I have the following struct that I want to read from JSON and Write to JSON. I want to read the PasswordHash property (deserialize it) but skip when writing the object (serialize it).

Is it possible to tag the object such that it that it is read when deserializing but ignored when serializing? the json:"-" seems to skip the field in both operations.

type User struct {

    // Must be unique
    UserName string

    // The set of projects to which this user has access
    Projects []string

    // A hash of the password for this user
    // Tagged to make it not serialize in responses
    PasswordHash string `json:"-"`

    // Is the user an admin
    IsAdmin bool
}

My deserialization code is as follows:

var user User
content = //Some Content
err := json.Unmarshal(content, &user)

and the serialization code is:

var userBytes, _ = json.Marshal(user)
var respBuffer bytes.Buffer
json.Indent(&respBuffer, userBytes, "", "   ")
respBuffer.WriteTo(request.ResponseWriter)

Upvotes: 1

Views: 226

Answers (2)

Kluyg
Kluyg

Reputation: 5347

I think you can't do that with json tags, but looks like the input user and the output user are actually different semantic objects. It's better to separate them in code too. This way it's easy to achieve what you want:

type UserInfo struct {
    // Must be unique
    UserName string

    // The set of projects to which this user has access
    Projects []string

    // Is the user an admin
    IsAdmin bool
} 

type User struct {
    UserInfo

    // A hash of the password for this user
    PasswordHash string
}

Your deserialization code stay the same. Serialization code is changed in one line:

var userBytes, _ = json.Marshal(user.UserInfo)

play.golang.com

Upvotes: 5

Mostafa
Mostafa

Reputation: 28126

You can’t do that with tags. You have to implement json.Marshaler to exclude the fields you want to exclude.

It would be a little tricky to write a MarshalJSON for the struct, because you don’t want to rewrite the whole marshaling. I recommend you have a type Password string, and write marshaler for that to return something empty as its JSON representation.

Upvotes: 1

Related Questions