Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unmarshal json field is int or string [duplicate]

Tags:

go

I have an app where the type is

type Person struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}

But we have legacy clients that send the Age field as either a string or an integer, so...

{
  "name": "Joe",
  "age": "42"
}

OR

{
  "name": "Joe",
  "age": 42
}

I know I can annotate the "age" field with ",string" if it's a string that I want coerced into an integer, but what if the field could be either one?

like image 312
MichaelB Avatar asked Nov 16 '25 18:11

MichaelB


1 Answers

Check out "json - raw Message" in the docs, from there on out you can try to parse it however you want. Example below and on GoPlayground

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "strconv"
    "unicode/utf8"
)

type Person struct {
    Name string          `json:"name"`
    Age  json.RawMessage `json:"age"`
}

func main() {
    var j = []byte(`{"name": "Joe","age": "42"}`)
    var j2 = []byte(`{"name": "Joe","age": 42}`)
    stringOrInt(j)
    stringOrInt(j2)
}

func stringOrInt(bytes []byte) {
    var p Person
    err := json.Unmarshal(bytes, &p)
    if err != nil {
        log.Fatal(err)
    }

    if utf8.Valid(p.Age) {
        i, err := strconv.Atoi(string(p.Age))
        if err != nil {
            fmt.Println("got int " + strconv.Itoa(i))
        } else {
            fmt.Println("got string")
        }
    } else {
        fmt.Println("whoops")
    }
}

like image 153
sHartmann Avatar answered Nov 18 '25 19:11

sHartmann