Deep Merge Configuration Maps

Merge layered JSON-like configuration maps recursively so nested objects combine while scalar overrides replace base values.

GoConfig Management

Code

snippet
package main

import (
	"encoding/json"
	"fmt"
)

func Merge(dst, src map[string]any) map[string]any {
	if dst == nil {
		dst = make(map[string]any)
	}
	for key, value := range src {
		if incoming, ok := value.(map[string]any); ok {
			if existing, ok := dst[key].(map[string]any); ok {
				dst[key] = Merge(existing, incoming)
				continue
			}
			dst[key] = Merge(nil, incoming)
			continue
		}
		dst[key] = value
	}
	return dst
}

func main() {
	base := map[string]any{
		"server": map[string]any{"port": 8080.0, "tls": false},
		"name":   "api",
	}
	override := map[string]any{
		"server": map[string]any{"port": 9090.0},
		"debug":  true,
	}
	merged := Merge(base, override)
	encoded, _ := json.Marshal(merged)
	fmt.Println(string(encoded))
}