使用Go语言解析嵌套的JSON

How could I parse and extract certain values from below JSON

Here is the sample JSON response

{
   "success":true,
   "endpoint":"https://api.abcxyz.com",
   "info":{
      "Guestconnected":134,
      "Guestratio":100000.06963,
      "symbol1":{
         "code":"NY",
         "symbol":"*",
         "name":"newyear",
         "codev":391.78161,
         "symbolAppearsAfter":false,
         "local":true
      },
      "symbol2":{
         "code":"HNY",
         "symbol":"@",
         "name":"HappyNewYear",
         "codev":1000000.0960,
         "symbolAppearsAfter":true,
         "local":false
      },
      "latest":{
         "value":1597509,
         "autovalue":"00099cf8da58a36c08f2ef98650ff6043ddfb",
         "height":474696,
         "time":1499527696
      }
   },
   "Allguest":{
      "all":4,
      "filtered":4,
      "total_invitations":15430,
      "sent_invitations":15430,
      "final_invitations":0
   },
   "Guestlist":[
      {
         "GuestCode":"369AR",
         "all":2,
         "total_invitations":5430,
         "sent_invitations":5430,
         "final_invitations":0,
         "change":0,
         "accounts":0
      },
      {
         "GuestCode":"6POIA96TY",
         "all":2,
         "total_invitations":10000,
         "sent_invitations":10000,
         "final_invitations":0,
         "change":0,
         "accounts":0
      }
   ]
}

My Code is :

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)


type object struct {
    Success bool `json:"success"`
    Endpoint string `json:"endpoint"`
    Allguest struct {
        All int `json:"all"`
        Filtered int `json:"filtered"`
        TotalInvitations int `json:"total_invitations"`
        SentInvitations int `json:"sent_invitations"`
        FinalInvitations int `json:"final_invitations"`
    } `json:"Allguest"`
    Guestlist []struct {
        GuestCode string `json:"GuestCode"`
        All int `json:"all"`
        TotalInvitations int `json:"total_invitations"`
        SentInvitations int `json:"sent_invitations"`
        FinalInvitations int `json:"final_invitations"`
        Change int `json:"change"`
        Accounts int `json:"accounts"`
    } `json:"Guestlist"`
}

func main() {

uri := "https://siteurl.com/api?lists=1"
res, err := http.Get(uri)
fmt.Println(uri)
if err != nil {
fmt.Println("Error:", err)
    log.Fatal(err)
}
defer res.Body.Close()

 var s object
err := json.NewDecoder(res.Body).Decode(&s)
if err != nil {
    log.Fatal(err)
    fmt.Println("Error:", err)
}
fmt.Println(s.Success)
fmt.Println(s.Allguest.TotalInvitations)
for i := 0; i < 6; i++ {
fmt.Println(s.Guestlist[i].TotalInvitations)
)

}

The problem is :

  1. If the response is null it is giving index out of range error how can we avoid this ?

  2. Applying condition if TotalInvitations value is greater than 100 then save in 100.csv else save in others.csv

use gjson pkg to get value from json document an simple way

example:

package main

import (
    "fmt"

    "github.com/tidwall/gjson"
)

func main() {
    data := []byte(`{
   "success": true,
   "endpoint": "https://api.abcxyz.com",
   "info": {
      "Guestconnected": 134,
      "Guestratio": 100000.06963,
      "symbol1": {
         "code": "NY",
         "symbol": "*",
         "name": "newyear",
         "codev": 391.78161,
         "symbolAppearsAfter": false,
         "local": true
      },
      "symbol2": {
         "code": "HNY",
         "symbol": "@",
         "name": "HappyNewYear",
         "codev": 1000000.096,
         "symbolAppearsAfter": true,
         "local": false
      },
      "latest": {
         "value": 1597509,
         "autovalue": "00099cf8da58a36c08f2ef98650ff6043ddfb",
         "height": 474696,
         "time": 1499527696
      }
   },
   "Allguest": {
      "all": 4,
      "filtered": 4,
      "total_invitations": 15430,
      "sent_invitations": 15430,
      "final_invitations": 0
   },
   "Guestlist": [
      {
         "GuestCode": "369AR",
         "all": 2,
         "total_invitations": 5430,
         "sent_invitations": 5430,
         "final_invitations": 0,
         "change": 0,
         "accounts": 0
      },
      {
         "GuestCode": "6POIA96TY",
         "all": 2,
         "total_invitations": 10000,
         "sent_invitations": 10000,
         "final_invitations": 0,
         "change": 0,
         "accounts": 0
      }
   ]
    }
    `)

    r := gjson.GetBytes(data, "Allguest.total_invitations")
    fmt.Println(r.Value()) // output 15430

    r = gjson.GetBytes(data, "Guestlist.#.total_invitations")
    fmt.Println(r.Value()) // output [5430 10000]
}
  1. If the response is null it is giving index out of range error how can we avoid this?

    Unless I'm misunderstanding you, the response being null shouldn't matter. If you receive 2 Guestlist items, you can only loop over those 2, meaning for i := 0; i < 6; i++ is wrong. Change it to for i := 0; i < len(s.Guestlist); i++ or for i := range s.Guestlist.

  2. Applying condition if TotalInvitations value is greater than 100 then save in 100.csv else save in others.csv

    You will probably want the os package's Create function to create a new file for writing or the OpenFile function, the O_CREATE, O_WRONLY, and O_APPEND file-open flags, and you can pass 0755 as the permission mode (or another set of octal permissions if you want to change access of a file).

    You can then use csvWriter := csv.NewWriter(csvFile) to wrap the resulting io.Writer (assuming there is no error opening the file). From there, you can just write whatever information you require to the file as CSV records. Don't forget to call csvWriter.Flush to flush the output buffer and csvWriter.Error to check whether there was an error flushing the output buffer. Also don't forget to close the file you opened.

If you need only certain entries from JSON you can define a structure with only those fields you are interested in. And if value can be null it is better to declare a pointer in the structure. Please take a look at an example at go playground: https://play.golang.org/p/mEwSXvPg3D