1

I am getting a json response from a server with three fix json object field and one field with different json objects.

Example - Response 1

{
   status : "success",
   error-code : "",
   message : "login successful",
   data : {
           token : "token value",
           refresh-token : "refresh token value"
          }
}

Example - Response 2

{
   status : "success",
   error-code : "",
   message : "user data fetched",
   data : {
           first-name: "josh",
           last-name : "walter",
           age : "30",
           phone: 1234567890,
           address : "x street, dc"
          }
}

for above json response created struct as follows

type loginData struct {
    Token string `json:"token"`
    RefreshToken string `json:"refresh-token"`

}

type userdata {
    FirstName string    `json:"first-name"`
    LastName string     `json:"refresh-token"`
    Age string          `json:"age"`
    Phone string        `json:"phone"`
    Address string      `json:"address"`

}


type response struct {
    Status string       `json:"status"`
    ErrorCode string    `json:"error-code"`
    RespMessage string  `json:"message"`
    RespData string     `json:"data"`
}



How to add logindata struct while unmarshaling during login response and userdata struct while unmarshaling userdata response in "RespData" field in response struct

0

3 Answers 3

2

First change the RespData field's type:

type response struct {
    Status      string      `json:"status"`
    ErrorCode   string      `json:"error-code"`
    RespMessage string      `json:"message"`
    RespData    interface{} `json:"data"`
}

Then, depending on what request you are making, set the RespData field to a pre-allocated instance of a pointer to the expected type:

r, err := http.Get("https://some_api.com/loginData")
if err != nil {
    return err
}
defer r.Body.Close()

// check r.StatusCode and make sure it's correct

data := loginData{}
resp := response{RespData: &data}
if err := json.NewDecoder(r.Body).Decode(&resp); err != nil {
    return err
}

fmt.Println(data)
Sign up to request clarification or add additional context in comments.

4 Comments

please check code below added answer
@supapati what for should I check the code in "below added answer"?
whether it is correct as you said to do..
@supapati if it works then it's correct, wouldn't you say so?
0

According to me, you should have two different structs to do this. One reason is separation of concern, as the structure of these responses may change in the future and these are responses from two different apis so its better to maintain different response objects.

type loginData struct {
    Token        string `json:"token"`
    RefreshToken string `json:"refresh-token"`
}

type userdata struct {
    FirstName string `json:"first-name"`
    LastName  string `json:"refresh-token"`
    Age       string `json:"age"`
    Phone     string `json:"phone"`
    Address   string `json:"address"`
}

type response struct {
    Status      string `json:"status"`
    ErrorCode   string `json:"error-code"`
    RespMessage string `json:"message"`
}

type userResponse struct {
    response
    RespData userdata `json:"data"`
}

type loginResponse struct {
    response
    RespData loginData `json:"data"`
}

3 Comments

I think this will workout will check n revert ..
I tried your suggestion but we get 27 different API responses in data field for each response, so have to create two struct each one child one parent. so there will be reusable code.
This will tedious if you have too many apis, I guess @mkopriva is an easier approach.
0

@mkopriva as you said tried this suggestion it worked.

package main

import (
    "encoding/json"
    "fmt"
    "strings"
)

type loginData struct {
    Token        string `json:"token"`
    RefreshToken string `json:"refresh-token"`
}

type userdata struct {
    FirstName string `json:"first-name"`
    LastName  string `json:"last-name"`
    Age       string `json:"age"`
    Phone     string `json:"phone"`
    Address   string `json:"address"`
}

type response struct {
    Status      string      `json:"status"`
    ErrorCode   string      `json:"error-code"`
    RespMessage string      `json:"message"`
    RespData    interface{} `json:"data"`
}

func main() {
    jsonresp_1 := `{
        "status" : "success",
        "error-code" : "",
        "message" : "login successful",
        "data" : {
                "token" : "token value",
                "refresh-token" : "refresh token value"
               }
     }`

    jsonresp_2 := `{
        "status" : "success",
        "error-code" : "",
        "message" : "user data fetched",
        "data" : {
                "first-name": "josh",
                "last-name" : "walter",
                "age" : "30",
                "phone": "1234567890",
                "address" : "x street, dc"
               }
     }`
    resp1 := strings.NewReader(jsonresp_1)
    data1 := loginData{}
    respdata1 := response{RespData: &data1}

    if err := json.NewDecoder(resp1).Decode(&respdata1); err != nil {
        fmt.Println(err)
    }
    fmt.Printf("token : %s \nrefreshtoken : %s \n", data1.Token, data1.RefreshToken)

    fmt.Println("-------------------")

    resp2 := strings.NewReader(jsonresp_2)
    data2 := userdata{}
    respdata2 := response{RespData: &data2}

    if err := json.NewDecoder(resp2).Decode(&respdata2); err != nil {
        fmt.Println(err)
    }
    fmt.Printf("firstname : %s \nlastname : %s ", data2.FirstName, data2.LastName)
}

Output

⚡ ⇒  go run main.go 
token : token value 
refreshtoken : refresh token value 
-------------------
firstname : josh 
lastname : walter

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.