Golang

Custom Unmarshal JSON in Golang

We could custom unmarshal JSON data that does not adhere to the struct we define.

E.g.

The crypto currency exchange GDAX market feed API:

https://docs.gdax.com/?javascript#get-product-order-book

Values returned are

{ 
"sequence": 3977318850, 
"bids": [ [ "4625.78", "0.80766325", 3 ] ], 
"asks": [ [ "4625.79", "3.0154341", 3 ] ]
}

The data within the array is

price, size, order_id

I converted this to a JSON struct using my favorite golang json converter  that has saved me so much time: https://mholt.github.io/json-to-go/

It gave me this golang struct.

type AutoGenerated struct {

Sequence int64 `json:"sequence"`
 Bids [][]interface{} `json:"bids"` 
Asks [][]interface{} `json:"asks"`

}

Ideally, I would like to define the dataset as below and Unmarshal the API contents into the struct

type Bid struct { 
   Price     string 
   Size      string 
NumOrders int
}

type OrderBook struct  { 
  Sequence int64 `json:"sequence"` 
  Bids     []Bid `json:"bids"` 
  Asks     []Bid `json:"asks"`
}
body, err := ioutil.ReadAll(resp.Body) 
if err != nil { 
  fmt.Println(err)
}
var orders OrderBook
err = json.Unmarshal(body, &orders) 
if err != nil { 
  fmt.Println(err)
} 

But the Unmarshaller will not automatically unmarshal into the above defined struct. It throws an error : json: cannot unmarshal array into Go value of Bid

To resolve this, all we need to do is define a Custom Unmarshaller  for our array to struct conversion:

func (b *Bid) UnmarshalJSON(data []byte) error { 
   var v []interface{} 
   if err := json.Unmarshal(data, &v); err != nil { 
     return err 
   } 
   b.Price, _ = v[0].(string) 
   b.Size, _ = v[1].(string) 
   b.NumOrders = int(v[2].(float64))
   return nil
}

 

And the Unmarshal on the main struct works seamlessly!

The full code is available on github at https://github.com/mariadesouza/go-orderbook.

 

 

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s