JSON → Go

Generate Go structs with json tags from a JSON sample.

Private by design. Your input never leaves this browser. Conversions run locally on your device.

What this tool handles

  • Emits Go structs with JSON tags matching the original key names.
  • The package line and omitempty tags can each be switched off.
  • Nested objects become their own named structs.
  • Pointer types are not generated. A key that was null in every record becomes interface{}; a key null in only some keeps its type and gains omitempty.

Example

JSON sample

{"id":1,"name":"Ada","active":true}

Go

package main

type Root struct {
	ID     int    `json:"id"`
	Name   string `json:"name"`
	Active bool   `json:"active"`
}

When you would use it

  • Unmarshalling a response you only have a sample of — The tag on each field carries the original key spelling, so encoding/json binds created_at or first-name to an exported Go field without any further mapping.
  • Field names a Go reviewer will accept — Known initialisms are capitalised in full, so user_id becomes UserID, apiURL becomes APIURL and ipAddress becomes IPAddress — the spelling revive and golint ask for, rather than UserId.
  • Finding out which fields are really optional — Paste an array of two or three captured responses instead of one. A key missing from some of them is the only evidence of optionality available, and it is what puts omitempty on that field.
  • Pasting into a file that already exists — Switching the package clause off emits the type declarations alone, so they drop into a models file that already has its own package line and imports.

Common questions

How do I tell an absent field from a null one?

With these types you cannot: both unmarshal to the zero value, so an empty string is indistinguishable from a key the server never sent. Change that field to a pointer, or to json.RawMessage, where the difference carries meaning.

What type does a timestamp or a price get?

A date string is typed string; time.Time is never emitted, so add it along with the parsing yourself. A whole number becomes int and a fractional one float64, so a price that happens to be 10 in the sample is typed int even though the endpoint can return 10.5.

What do I get from a top-level JSON array?

Only the struct for the element, named after your root name with a 2 appended because the root name is already taken. No named slice type is declared, so write []Root2 at the call site.

How are empty or mixed values typed?

An empty array becomes []interface{} and an empty object map[string]interface{}. An array whose elements are of different types also collapses to []interface{}, since a single slice type has to cover all of them.

Related tools

Browse all 25 tools