go 45 lines · 7 steps

Parsing untyped JSON config in Go

How to safely walk a dynamic JSON blob and build a map of service URLs using type assertions.

Explained by highlit
1package config
2 
3import (
4 "encoding/json"
5 "fmt"
6)
7 
8func ExtractServiceEndpoints(raw []byte) (map[string]string, error) {
9 var doc map[string]interface{}
10 if err := json.Unmarshal(raw, &doc); err != nil {
11 return nil, fmt.Errorf("invalid config json: %w", err)
12 }
13 
14 services, ok := doc["services"].(map[string]interface{})
15 if !ok {
16 return nil, fmt.Errorf("missing or malformed 'services' object")
17 }
18 
19 endpoints := make(map[string]string, len(services))
20 for name, entry := range services {
21 cfg, ok := entry.(map[string]interface{})
22 if !ok {
23 continue
24 }
25 
26 host, _ := cfg["host"].(string)
27 if host == "" {
28 return nil, fmt.Errorf("service %q has no host", name)
29 }
30 
31 port := 80
32 if p, ok := cfg["port"].(float64); ok {
33 port = int(p)
34 }
35 
36 scheme := "http"
37 if tls, ok := cfg["tls"].(bool); ok && tls {
38 scheme = "https"
39 }
40 
41 endpoints[name] = fmt.Sprintf("%s://%s:%d", scheme, host, port)
42 }
43 
44 return endpoints, nil
45}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Unmarshaling into map[string]interface{} lets you handle JSON whose shape you don't know at compile time.
  2. 2Comma-ok type assertions turn risky casts into safe branches you can validate or default.
  3. 3JSON numbers always decode to float64 in Go, so numeric fields need an explicit conversion.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Parsing untyped JSON config in Go — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code