Search code examples
jsongomongo-go

Is there a way to convert a JSON string into a Mongo extended JSON using Go?


I have a sample JSON body that contains some strings. I want some of the strings to be converted into Mongo Extended JSON. For example, the JSON body passed in is the following:

{
    "GuidBinary": "734cba69-4851-4869-8d0e-e870d6fb3065",
    "DateTime": "12/12/2012",
    "RegularString": "abcd"
}

And I want to convert this into

{
    "GuidBinary": {
        "$binary": {
            "base64": "<payload>",
            "subType": 0x03
        }
    },
    "DateTime": {"$date": "<ISO-8601 Date/Time Format>"},
    "RegularString": "abcd"
}

Is there a way to do this in Go, either through a package like mongo-go-driver or another method?


Solution

  • Yes, it's possible. It's part of the official mongo-go driver. Generating this extended JSON is published as the bson.MarshalExtJSON() function.

    Example using it:

    m := map[string]interface{}{
        "GuidBinary":    []byte{1, 2, 3, 4, 5},
        "DateTime":      time.Now(),
        "RegularString": "abcd",
    }
    
    out, err := bson.MarshalExtJSON(m, false, false)
    fmt.Println(string(out), err)
    

    This will output (try it on the Go Playground):

    {"DateTime":{"$date":"2009-11-10T23:00:00Z"},"RegularString":"abcd",
        "GuidBinary":{"$binary":{"base64":"AQIDBAU=","subType":"00"}}} <nil>
    

    So what you need to do is unmarshal your original JSON (using the encoding/json package), and you need to do some post processing on it: GuidBinary is a regular string in the input JSON, but it represents a UUID. You need to parse it into a UUID value (there are probably lots of libraries for this).

    You also need to convert (parse) the DateTime which is also given as a JSON text in the input, but it represents a date. Use time.Parse() for this. And now you can call bson.MarshalExtJSON() to generate the extended JSON.