Search code examples
jsonhttpgogoland

Parse unstructured json in golang


Is there any solution to parse an unstructured json(text) data? below is a sample response of a web requst that i want to parse and access data (the inner list)

res,err := http.Get("url_of_server")
[[
    {
        "id": "1",
        "text": "sample text",
        "user": {
          "user_id": "1",
          "username": "user1"
        },
        "created_at_utc": "2022-12-20T16:38:06+00:00",
        "status": "Active"
      },
      {
        "id": "2",
        "text": "sample text",
        "user": {
          "user_id": "2",
          "username": "user2"
        },
        "created_at_utc": "2022-12-01T10:15:00+00:00",
        "status": "Active"
      }
],
"{"code": "hsdvnkvuahudvhafdlfv",
  "is_updated": true}", 
 null
]

what i want to get is:

[
    {
        "id": "1",
        "text": "sample text",
        "user": {
          "user_id": "1",
          "username": "user1"
        },
        "created_at_utc": "2022-12-20T16:38:06+00:00",
        "status": "Active"
      },
      {
        "id": "2",
        "text": "sample text",
        "user": {
          "user_id": "2",
          "username": "user2"
        },
        "created_at_utc": "2022-12-01T10:15:00+00:00",
        "status": "Active"
      }
]

in python it is possible by easily using res.json()[0]

I have tried using json.Unmarshal() to a map and also struct but does not work, i don't know how to get rid of this part of response:

"{"code": "hsdvnkvuahudvhafdlfv",
  "is_updated": true}", 
 null

Solution

  • Declare a type for the items:

    type Item struct {
        ID   string `json:"id"`
        Text string `json:"text"`
        User struct {
            UserID   string `json:"user_id"`
            Username string `json:"username"`
        } `json:"user"`
        CreatedAtUtc time.Time `json:"created_at_utc"`
        Status       string    `json:"status"`
    }
    

    Declare a slice of the items:

    var items []Item
    

    Declare a slice representing the entire JSON thing. The first element is the items.

    var v = []any{&items}
    

    Unmarshal to v. The items slice will have the values that you are looking for. The second and third elements of v will contain the values you want to ignore.

    err := json.Unmarshal(data, &v)
    

    Run the code in the GoLang PlayGround.