Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
how to unmarshal a custom type in go
package main
import (
type theStruct struct {
Thing string
// UnmarshalJSON unmarshals the bytes into the struct, performing custom
// error checking on the struct values
func (t *theStruct) UnmarshalJSON(data []byte) error {
fmt.Println("unmarshaling in my custom handler")
type structAlias theStruct
aux := &struct {
structAlias: (*structAlias)(t),
err := json.Unmarshal(data, aux)
if err != nil {
return err
// perform custom checking on the aux struct
if aux.Thing == "doesn't work" {
return fmt.Errorf("value for Thing is invalid : %s", aux.Thing)
// it's all good - put it in the pointer we're working with
// if we wanted we could manually set all the fields or for laziness we
// could just use a library like this :-)
return copier.Copy(t, aux)
func main() {
// marshal a dummy struct into the bytes
t := theStruct{
Thing: "doesn't work",
data, err := json.Marshal(t)
if err != nil {
// turn the bytes into an io.Reader and
// try to decode these bytes into the struct
dest := theStruct{}
err = json.NewDecoder(bytes.NewReader(data)).Decode(&dest)
if err != nil {
// do it again with a struct that passes the validation
src2 := theStruct{
Thing: "works",
data2, err := json.Marshal(&src2)
if err != nil {
dest2 := theStruct{}
err = json.NewDecoder(bytes.NewReader(data2)).Decode(&dest2)
if err != nil {
fmt.Printf("%+v\n", dest2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.