Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Parse JSON objects with arbitrary key names in Go using interfaces and type assertions
// Parsing arbitrary JSON using interfaces in Go
// Demonstrates how to parse JSON with abritrary key names
// See for more info on generic JSON parsing
package main
import (
var jsonBytes = []byte(`
"Item1": "Value1",
"Item2": 1},
"Item1": "Value2",
"Item2": 2},
"Item1": "Value3",
"Item2": 3}
// Item struct; we want to create these from the JSON above
type Item struct {
Item1 string
Item2 int
// Implement the String interface for pretty printing Items
func (i Item) String() string {
return fmt.Sprintf("Item: %s, %d", i.Item1, i.Item2)
func main() {
// Unmarshal using a generic interface
var f interface{}
err := json.Unmarshal(jsonBytes, &f)
if err != nil {
fmt.Println("Error parsing JSON: ", err)
// JSON object parses into a map with string keys
itemsMap := f.(map[string]interface{})
// Loop through the Items; we're not interested in the key, just the values
for _, v := range itemsMap {
// Use type assertions to ensure that the value's a JSON object
switch jsonObj := v.(type) {
// The value is an Item, represented as a generic interface
case interface{}:
var item Item
// Access the values in the JSON object and place them in an Item
for itemKey, itemValue := range jsonObj.(map[string]interface{}) {
switch itemKey {
case "Item1":
// Make sure that Item1 is a string
switch itemValue := itemValue.(type) {
case string:
item.Item1 = itemValue
fmt.Println("Incorrect type for", itemKey)
case "Item2":
// Make sure that Item2 is a number; all numbers are transformed to float64
switch itemValue := itemValue.(type) {
case float64:
item.Item2 = int(itemValue)
fmt.Println("Incorrect type for", itemKey)
fmt.Println("Unknown key for Item found in JSON")
// Not a JSON object; handle the error
fmt.Println("Expecting a JSON object; got something else")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment