Noções Básicas de Serialização
10 exemplos para você começar com Serialização - 7 básicos e 3 intermediários.
Busque em todas as páginas da documentação
10 exemplos para você começar com Serialização - 7 básicos e 3 intermediários.
mkdir serdemo && cd serdemo && go mod init example.com/serdemo.main.go (ou arquivos separados em um pacote) e execute com go run ..Viagem de ida e volta de uma struct através de bytes JSON.
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
func main() {
u := User{ID: 1, Name: "Ada"}
b, err := json.Marshal(u)
if err != nil {
panic(err)
}
fmt.Println(string(b))
var decoded User
if err := json.Unmarshal(b, &decoded); err != nil {
panic(err)
}
fmt.Println(decoded.Name)
}Marshal retorna []byte; converta com string(b) para imprimir.Unmarshal precisa de um ponteiro para o valor de destino.Relacionado: Serialização em Go: JSON Primeiro, Formatos Sob Demanda - por que JSON é o padrão
Tags renomeiam campos e ocultam internos.
package main
import (
"encoding/json"
"fmt"
)
type Account struct {
Login string `json:"login"`
PasswordHash string `json:"-"`
Role string `json:"role,omitempty"`
}
func main() {
a := Account{Login: "ada", PasswordHash: "secret"}
b, _ := json.Marshal(a)
fmt.Println(string(b))
}json:"login" mapeia Login para a chave "login".json:"-" exclui PasswordHash da saída completamente.omitempty descarta campos de valor zero, como Role vazio.Relacionado: Tags de Struct para JSON, DB e Validação - convenções multi-tag
Ponteiros distinguem "ausente" de "presente zero".
package main
import (
"encoding/json"
"fmt"
)
type Item struct {
Qty int `json:"qty"`
Notes *string `json:"notes,omitempty"`
}
func main() {
empty := Item{Qty: 0}
b1, _ := json.Marshal(empty)
fmt.Println(string(b1))
note := ""
withPtr := Item{Qty: 1, Notes: ¬e}
b2, _ := json.Marshal(withPtr)
fmt.Println(string(b2))
}Qty com valor 0 ainda aparece, a menos que você adicione omitempty.Notes como nil é omitido com omitempty; um ponteiro para "" é mantido.null explícita.Relacionado: Evolução de Esquema e Tratamento de Campos Desconhecidos - campos opcionais
Coleções codificam como arrays e objetos JSON.
package main
import (
"encoding/json"
"fmt"
)
func main() {
tags := []string{"go", "json"}
meta := map[string]int{"a": 1, "b": 2}
b1, _ := json.Marshal(tags)
b2, _ := json.Marshal(meta)
fmt.Println(string(b1))
fmt.Println(string(b2))
}nil codificam como null; slices vazios codificam como [] quando não são nil.encoding.TextMarshaler).map[string]any para contratos de API estáveis.Relacionado: Serialização Personalizada do encoding/json - alternativas tipadas a mapas
Transmita JSON para io.Writer e de io.Reader.
package main
import (
"bytes"
"encoding/json"
"fmt"
)
type Event struct {
Type string `json:"type"`
}
func main() {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
_ = enc.Encode(Event{Type: "click"})
dec := json.NewDecoder(&buf)
var e Event
_ = dec.Decode(&e)
fmt.Println(e.Type)
}Encode anexa uma nova linha após cada valor (amigável para JSON Lines).Relacionado: Melhores Práticas de Serialização - limites de tamanho em corpos
Embutimento anônimo achata a saída JSON.
package main
import (
"encoding/json"
"fmt"
)
type Timestamps struct {
CreatedAt string `json:"created_at"`
}
type Post struct {
Timestamps
Title string `json:"title"`
}
func main() {
p := Post{Timestamps: Timestamps{CreatedAt: "2026-01-01"}, Title: "Hi"}
b, _ := json.Marshal(p)
fmt.Println(string(b))
}Relacionado: Serialização Personalizada do encoding/json - padrões de serializador personalizados
MarshalIndent formata a saída durante o desenvolvimento.
package main
import (
"encoding/json"
"fmt"
)
func main() {
data := map[string]any{"ok": true, "count": 3}
b, _ := json.MarshalIndent(data, "", " ")
fmt.Println(string(b))
}Relacionado: JSON de Alto Desempenho: Alternativas jsoniter & sonic - quando a velocidade compacta importa
Substitua a codificação padrão de data/hora RFC3339.
package main
import (
"encoding/json"
"fmt"
"time"
)
type DateOnly time.Time
func (d DateOnly) MarshalJSON() ([]byte, error) {
t := time.Time(d)
return json.Marshal(t.Format("2006-01-02"))
}
func main() {
d := DateOnly(time.Date(2026, 7, 15, 0, 0, 0, 0, time.UTC))
b, _ := json.Marshal(d)
fmt.Println(string(b))
}time.Time já implementa MarshalJSON com RFC3339; novos tipos o envolvem para outros layouts.MarshalJSON com UnmarshalJSON para APIs simétricas.Relacionado: Serialização Personalizada do encoding/json - padrões de serializador personalizados completos
Mantenha JSON desconhecido ou parcial até saber o esquema.
package main
import (
"encoding/json"
"fmt"
)
type Envelope struct {
Type string `json:"type"`
Payload json.RawMessage `json:"payload"`
}
func main() {
raw := []byte(`{"type":"user","payload":{"id":1}}`)
var env Envelope
_ = json.Unmarshal(raw, &env)
fmt.Println(env.Type, string(env.Payload))
}RawMessage é um alias de []byte que atrasa a decodificação aninhada.Type.Relacionado: Evolução de Esquema e Tratamento de Campos Desconhecidos - padrões de evolução
Rejeite requisições com chaves inesperadas.
package main
import (
"bytes"
"encoding/json"
"fmt"
)
type CreateUser struct {
Name string `json:"name"`
}
func main() {
body := []byte(`{"name":"Ada","admin":true}`)
dec := json.NewDecoder(bytes.NewReader(body))
dec.DisallowUnknownFields()
var req CreateUser
err := dec.Decode(&req)
fmt.Println(err)
}Relacionado: Validação com go-playground/validator - regras pós-decodificação
Versões da Stack: Esta página foi escrita para Go 1.26.x (GC padrão Green Tea, modernizadores go fix - verifique o patch na compilação), chi (mais recente - verifique na compilação), gin (mais recente - verifique na compilação), echo (mais recente - verifique na compilação), google.golang.org/grpc (mais recente - verifique na compilação), sigs.k8s.io/controller-runtime (mais recente - verifique na compilação), kubebuilder (mais recente - verifique na compilação), tinygo (mais recente - verifique os alvos de placa na compilação), wazero (mais recente - verifique na compilação) e golangci-lint (mais recente - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026