JSON Encoding in Go: Dealing with Sensitive Fields
Tuesday, January 20, 2015 at 10:21PM
Blake Caldwell

JSON marshalling in Go is pretty straight-forward, but sometimes your structs contain sensitive information that you'd like to keep out of your public JSON API. Fortunately, there are a few good solutions that don't require you to manually copy every field from one struct type to another.

Let's start with our basic Person struct:

The simplest way to prevent exposing AuthToken via JSON is with the `json:"-"` key, which tells the JSON package to always ignore this field. Let's call this "SafePerson", because you never have to worry about exposing AuthToken via JSON:

This works really well, until you need to include the field some of the time, like when showing someone their own record. In that case, you could try the `json:",omitempty"` key, which only includes the field if it has a value. It'd be up to you to clear it out when it doesn't belong in the JSON. This is "PrettySafePerson", because it's safe if you're careful:

This is great, but... here's the thing. That one time you forget to clear an AuthToken for someone other than the Person that it represents might give you quite the headache. I'd rather err on the side of safety, where forgetting something means not showing data that I meant to. 

Here's where we can take advantage of Go's type embedding. By embedding a Person inside another struct, we borrow all of the Person's fields, and can override some without affecting the Person. We'll build our API with this pattern, which always omit sensitive fields unless told otherwise:

PublicPerson's AuthToken field overrides the embedded Person.AuthToken, and because of the `json:",omitempty"` key, it'll be hidden from JSON unless you set it. Person.AuthToken still has the original value, you can include it in the JSON by calling IncludeAuthToken().

Try it out in the Go Playground

View Source on Github

Article originally appeared on Blake Caldwell (http://blakecaldwell.net/).
See website for complete article licensing information.