I have the following json:
{
"app": {
"name": "name-of-app",
"version" 1
},
"items": [
{
"type": "type-of-item",
"inputs": {
"input1": "value1"
}
}
]
}
The items[0].inputs
change based on the items[0].type
.
Knowing that, is there a way to keep the inputs
field a string? The idea is to use the type
to call the right handler passing the inputs
, and in there I would parse the inputs
string using the right struct.
Example:
package main
import (
"fmt"
"encoding/json"
)
type Configuration struct {
App App `json:"app"`
Items []Item `json:"items"`
}
type App struct {
Name string `json:"name"`
Version int `json:"version"`
}
type Item struct {
Type string `json:"type"`
// What to put here to mantain the field a string so I can Unmarshal later?
// Inputs string
}
var myJson = `
{
"app": {
"name": "name-of-app",
"version": 1
},
"items": [
{
"type": "type-of-item",
"inputs": {
"input1": "value1"
}
}
]
}
`
func main() {
data := Configuration{}
json.Unmarshal([]byte(myJson), &data)
fmt.Println("done!", data)
// Loop through data.Items and use the type to define what to call, and pass inputs
// as argument
}
Thank you in advance.
json is read with the ioutil. ReadFile() function, which returns a byte slice that is decoded into the struct instance using the json. Unmarshal() function. At last, the struct instance member values are printed using for loop to demonstrate that the JSON file was decoded.
To parse JSON, we use the Unmarshal() function in package encoding/json to unpack or decode the data from JSON to a struct. Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. Note: If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
To unmarshal a JSON array into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. As a special case, to unmarshal an empty JSON array into a slice, Unmarshal replaces the slice with a new empty slice.
Use json.RawMessage to get the raw JSON text of the inputs
field:
type Item struct {
Type string `json:"type"`
Inputs json.RawMessage
}
Use it like this:
var data Configuration
if err := json.Unmarshal([]byte(myJson), &data); err != nil {
// handle error
}
// Loop over items and unmarshal items.Inputs to Go type specific
// to each input type.
for _, item := range data.Items {
switch item.Type {
case "type-of-item":
var v struct{ Input1 string }
if err := json.Unmarshal(item.Inputs, &v); err != nil {
// handle error
}
fmt.Printf("%s has value %+v\n", item.Type, v)
}
}
Run it on the playground.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With