Reputation: 73
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
Upvotes: 1
Views: 1379
Reputation: 73
@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)
}
⚡ ⇒ go run main.go
token : token value
refreshtoken : refresh token value
-------------------
firstname : josh
lastname : walter
Upvotes: 0
Reputation: 365
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"`
}
Upvotes: 0
Reputation: 38343
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)
Upvotes: 2