Get x-www-form-urlencoded key-value pair as JSON in Go

I need to parse x-www-form-urlencoded body with nested key-value to get JSON format.

I’m trying to parse an x-www-form-urlencoded body with nested key-value pairs into a JSON format. I have used url.ParseQuery and r.Form, but neither of these have returned the expected result of:

{
  "name": "abc",
  "age": 12,
  "notes": {
    "key1": "value1",
    "key2": "value2"
  }
}

The input body is:

name=abc&age=12&notes[key1]=value1&notes[key2]=value2

The output of url.ParseQuery and r.Form is:

{
  "name": "abc",
  "age": 12,
  "notes[key1]": "value1",
  "notes[key2]": "value2"
}

The body may contain up to three levels of nested key-value pairs. How can I parse the x-www-form-urlencoded body to get the desired JSON format?

To parse the x-www-form-urlencoded body with nested key-value pairs into the desired JSON format, you can use the following code:

package main

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

func main() {
	body := "name=abc&age=12&notes[key1]=value1&notes[key2]=value2"

	data := make(map[string]interface{})
	values, _ := url.ParseQuery(body)

	for key, value := range values {
		nestedKeys := strings.Split(key, "[")
		lastKey := nestedKeys[len(nestedKeys)-1][:len(nestedKeys[len(nestedKeys)-1])-1]

		if len(nestedKeys) > 1 {
			current := data

			for i := 0; i < len(nestedKeys)-1; i++ {
				if _, ok := current[nestedKeys[i]]; !ok {
					current[nestedKeys[i]] = make(map[string]interface{})
				}

				current = current[nestedKeys[i]].(map[string]interface{})
			}

			current[lastKey] = value[0]
		} else {
			data[lastKey] = value[0]
		}
	}

	jsonData, _ := json.MarshalIndent(data, "", "  ")
	fmt.Println(string(jsonData))
}

This code will output the desired JSON format:

{
  "name": "abc",
  "age": "12",
  "notes": {
    "key1": "value1",
    "key2": "value2"
  }
}

The code splits each key by “[” to identify nested keys. It then iterates over the nested keys and creates nested maps accordingly. Finally, it assigns the corresponding value to the last key in the nested structure.

Note that the values are stored as strings in the resulting JSON since the input body contains only string values. If you want to parse values into their respective types, you can modify the code accordingly.