Today I encountered an API which sometimes sends back numbers as strings.
Example response:
{
"age": "30"
}
That’s annoying, because I wanted my struct in Go to be like this:
type Person struct {
Age int `json:"age"`
}
I learned that json struct tags have a string option meant for dealing with exactly this sort of problem:
The “string” option signals that a field is stored as JSON inside a JSON-encoded string. It applies only to fields of string, floating point, integer, or boolean types. This extra level of encoding is sometimes used when communicating with JavaScript programs:
Changing my struct to this worked great!
type Person struct {
Age int `json:"age,string"`
}
Test program:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Age int `json:"age,string"`
}
func main() {
// Test 1
p1 := Person{Age: 30}
b1, _ := json.Marshal(p1)
fmt.Println("Test 1:", string(b1))
// Test 2
s2 := `{"age":"30zz"}`
var p2 Person
_ = json.Unmarshal([]byte(s2), &p2)
fmt.Println("Test 2:", p2)
// Test 3
s3 := `{"age":30}`
var p3 Person
if err := json.Unmarshal([]byte(s3), &p3); err != nil {
fmt.Println("Test 3:", err)
}
fmt.Println("Test 3:", p3)
}
Output:
Test 1: {"age":"30"}
Test 2: {0}
Test 3: json: invalid use of ,string struct tag, trying to unmarshal unquoted value into int
Test 3: {0}