Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode json into structs

Tags:

json

go

I'm trying to decode some json in Go but some fields don't get decoded. See the code running in browser here:

What am I doing wrong?

I need only the MX records so I didn't define the other fields. As I understand from the godoc you don't need to define the fields you don't use/need.

// You can edit this code!
// Click here and start typing.
package main

import "fmt"
import "encoding/json"

func main() {

    body := `
  {"response": {
  "status": "SUCCESS",
  "data": {
    "mxRecords": [
      {
        "value": "us2.mx3.mailhostbox.com.",
        "ttl": 1,
        "priority": 100,
        "hostName": "@"
      },
      {
        "value": "us2.mx1.mailhostbox.com.",
        "ttl": 1,
        "priority": 100,
        "hostName": "@"
      },
      {
        "value": "us2.mx2.mailhostbox.com.",
        "ttl": 1,
        "priority": 100,
        "hostName": "@"
      }
    ],
    "cnameRecords": [
      {
        "aliasHost": "pop.a.co.uk.",
        "canonicalHost": "us2.pop.mailhostbox.com."
      },
      {
        "aliasHost": "webmail.a.co.uk.",
        "canonicalHost": "us2.webmail.mailhostbox.com."
      },
      {
        "aliasHost": "smtp.a.co.uk.",
        "canonicalHost": "us2.smtp.mailhostbox.com."
      },
      {
        "aliasHost": "imap.a.co.uk.",
        "canonicalHost": "us2.imap.mailhostbox.com."
      }
    ],
    "dkimTxtRecord": {
      "domainname": "20a19._domainkey.a.co.uk",
      "value": "\"v=DKIM1; g=*; k=rsa; p=DkfbhO8Oyy0E1WyUWwIDAQAB\"",
      "ttl": 1
    },
    "spfTxtRecord": {
      "domainname": "a.co.uk",
      "value": "\"v=spf1 redirect=_spf.mailhostbox.com\"",
      "ttl": 1
    },
    "loginUrl": "us2.cp.mailhostbox.com"
  }
}}`

    type MxRecords struct {
        value    string
        ttl      int
        priority int
        hostName string
    }



    type Data struct {
        mxRecords []MxRecords
    }

    type Response struct {
        Status string `json:"status"`
        Data   Data   `json:"data"`
    }
    type apiR struct {
        Response Response
    }

    var r apiR
    err := json.Unmarshal([]byte(body), &r)
    if err != nil {
        fmt.Printf("err was %v", err)
    }
    fmt.Printf("decoded is %v", r)

}
like image 350
user3721073 Avatar asked Jun 19 '14 06:06

user3721073


2 Answers

As per the go documentaiton about json.Unmarshal, you can only decode toward exported fields, the main reason being that external packages (such as encoding/json) cannot acces unexported fields.

If your json doesn't follow the go convention for names, you can use the json tag in your fields to change the matching between json key and struct field.

Exemple:

package main

import (
    "fmt"
    "encoding/json"
)

type T struct {
    Foo  string `json:"foo"`
    priv string `json:"priv"`
}

func main() {
    text := []byte(`{"foo":"bar", "priv":"nothing"}`)
    var t T
    err := json.Unmarshal(text, &t)
    if err != nil {
        panic(err)
    }
    fmt.Println(t.Foo) // prints "bar"
    fmt.Println(t.priv) // prints "", priv is not exported
}
like image 120
Elwinar Avatar answered Oct 12 '22 20:10

Elwinar


You must Uppercase struct fields:

type MxRecords struct {
    Value    string `json:"value"`
    Ttl      int    `json:"ttl"`
    Priority int    `json:"priority"`
    HostName string `json:"hostName"`
}

type Data struct {
    MxRecords []MxRecords `json:"mxRecords"`
}

http://play.golang.org/p/EEyiISdoaE

like image 22
leiyonglin Avatar answered Oct 12 '22 21:10

leiyonglin