Json – Removing fields from struct or hiding them in JSON Response

gojson

I've created an API in Go that, upon being called, performs a query, creates an instance of a struct, and then encodes that struct as JSON before sending back to the caller. I'd now like to allow the caller to be able to select the specific fields they would like returned by passing in a "fields" GET parameter.

This means depending on the fields value(s), my struct would change. Is there any way to remove fields from a struct? Or at least hide them in the JSON response dynamically? (Note: Sometimes I have empty values so the JSON omitEmpty tag will not work here) If neither of these are possible, is there a suggestion on a better way to handle this?

A smaller version of the structs I'm using are below:

type SearchResult struct {
    Date        string      `json:"date"`
    IdCompany   int         `json:"idCompany"`
    Company     string      `json:"company"`
    IdIndustry  interface{} `json:"idIndustry"`
    Industry    string      `json:"industry"`
    IdContinent interface{} `json:"idContinent"`
    Continent   string      `json:"continent"`
    IdCountry   interface{} `json:"idCountry"`
    Country     string      `json:"country"`
    IdState     interface{} `json:"idState"`
    State       string      `json:"state"`
    IdCity      interface{} `json:"idCity"`
    City        string      `json:"city"`
} //SearchResult

type SearchResults struct {
    NumberResults int            `json:"numberResults"`
    Results       []SearchResult `json:"results"`
} //type SearchResults

I then encode and output the response like so:

err := json.NewEncoder(c.ResponseWriter).Encode(&msg)

Best Answer

The question is asking for fields to be dynamically selected based on the caller-provided list of fields. This isn't possible to be done with the statically-defined json struct tag.

If what you want is to always skip a field to json-encode, then of course use json:"-" to ignore the field. (Note also that this is not required if your field is unexported; those fields are always ignored by the json encoder.) This isn't what the question asks.

To quote the comment on the json:"-" answer:

This [the json:"-" answer] is the answer most people ending up here from searching would want, but it's not the answer to the question.

I'd use a map[string]interface{} instead of a struct in this case. You can easily remove fields by calling the delete built-in on the map for the fields to remove.

That is, if you can't query only for the requested fields in the first place.

Related Topic