'how to build a nested, dynamic JSON in Go

I'm writing a simple API in Go that reads from a database and outputs GeoJSON.

I have this working for simple points. But some of my data is lines (linestring). I would like to have a generic GeoJSON struct definition. However, as specified in GeoJSON, the "Features" element has a "Coordinates" sub-element, which contains either a [2]float32 point coordinates, OR an array of points for lines and polygons.

Is there a way to define a struct in Go in such a way? I come from PHP and with the weakly typed arrays there it would be trivial.

If I can't do it with a struct - what else except puzzling together a string is the proper approach in Go?

Note: Similar questions are all about unmarshaling a dynamic JSON. I need to build one from the database contents.



Solution 1:[1]

You can create a map[string]any, set its value for Coordinates and then marshal that. Like this for example:

package main

import (
    "encoding/json"
    "fmt"
)

type Point struct {
    X, Y int
}

func main() {
    m := map[string]any{}
    var singleCoordinate bool
    if singleCoordinate {
        m["Coordinates"] = []float32{1, 2}
    } else {
        m["Coordinates"] = []Point{{X: 1, Y: 2}, {X: 2, Y: 2}}
    }
    data, err := json.Marshal(m)
    fmt.Println(string(data), err)
}

Playground: https://go.dev/play/p/8mJHJ-e-kyX

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1