JSON to Go
The result appears here.
Generate
Your document never leaves the browser.
Go structs with json tags, from a JSON sample — in your browser, never uploaded.
Paste the JSON an API returns and get structs that encoding/json unmarshals it into. Field names follow Go’s conventions, and every field keeps its original key in a json tag.
Each object becomes a struct and each key an exported field, with the JSON name in its tag. Go’s initialisms are respected, so order_id becomes OrderID, not OrderId. Whole numbers are int64 and numbers with a fraction float64, and the fields are aligned the way gofmt aligns them.
gift-wrap is missing from one line item, so by default it is *bool with omitempty: nil means the key was not there, and a false you set is still written out. note is sometimes null and sometimes a string, and Go has no nullable string, so it is any, with a comment listing nil and string as the values that were seen.
The sample, an order with two line items, pasted as the source
{
"order_id": 1042,
"placed_at": "2026-09-25T10:15:00Z",
"paid": true,
"customer": { "name": "Ada Lovelace", "email": "[email protected]" },
"items": [
{ "sku": "PEN-01", "qty": 2, "price": 3.5, "note": null },
{ "sku": "INK-07", "qty": 1, "price": 12, "note": "Fragile", "gift-wrap": true }
]
}The structs written for it
package main
type Customer struct {
Name string `json:"name"`
Email string `json:"email"`
}
type Item struct {
Sku string `json:"sku"`
Qty int64 `json:"qty"`
Price float64 `json:"price"`
Note any `json:"note"` // one of: nil, string
GiftWrap *bool `json:"gift-wrap,omitempty"`
}
type Root struct {
OrderID int64 `json:"order_id"`
PlacedAt string `json:"placed_at"`
Paid bool `json:"paid"`
Customer Customer `json:"customer"`
Items []Item `json:"items"`
}The sample, with Optional fields omitempty only
package main
type Customer struct {
Name string `json:"name"`
Email string `json:"email"`
}
type Item struct {
Sku string `json:"sku"`
Qty int64 `json:"qty"`
Price float64 `json:"price"`
Note any `json:"note"` // one of: nil, string
GiftWrap bool `json:"gift-wrap,omitempty"`
}
type Root struct {
OrderID int64 `json:"order_id"`
PlacedAt string `json:"placed_at"`
Paid bool `json:"paid"`
Customer Customer `json:"customer"`
Items []Item `json:"items"`
}Option
Package: main by default. Type the package the file will live in.
Option
Optional fields: *T, omitempty, the default, or omitempty only, which keeps plain value types and gives up telling a missing key from a zero value.
An integer past int64 is typed json.Number, and the file imports encoding/json for it, so the digits arrive as text and nothing is rounded. Call its String method to keep the value exact, or Int64 once you know it fits.
Nested structs take their names from their keys, customer giving Customer, and a slice of objects takes the singular, so items is []Item. A list holding more than one type is []any with a comment naming its element types, and a key starting with a digit gets a letter in front, so 2fa becomes F2Fa. Check a number that happened to be whole in your sample but can carry a fraction elsewhere: it will be int64 here, and unmarshalling 2.5 into it fails.
A 20-digit account number, a key starting with a digit, and a mixed list
{ "account": 12345678901234567890, "2fa": true, "codes": [1, "A"] }json.Number with its import, F2Fa and []any
package main
import "encoding/json"
type Root struct {
Account json.Number `json:"account"`
F2Fa bool `json:"2fa"`
Codes []any `json:"codes"` // elements: int64, string
}Inference and code generation both run inside this browser tab. The sample is never uploaded, stored on a server or logged, because the page has no server to send it to, and once loaded it carries on working with the connection off.
Declare a variable of the root type and pass its address to json.Unmarshal, or to a json.Decoder reading the response body.
Because its values differed in type between records, or it was null where others were text. Replace any with the type you expect once you know it.
No, only json tags. Adding a yaml or bson tag beside each one is a quick edit in most editors.