Home >Backend Development >Golang >How to create a sorted key-value map that can be serialized to json by Gin?
When developing web applications using Go language, it often involves serializing data into JSON format. For the serialization of sorted key-value mapping, we can use the Gin framework and the map data structure in Golang to achieve it. In this article, PHP editor Banana will introduce you in detail how to create a sorted key-value map that can be serialized into JSON by Gin, making your web application more flexible and efficient. Let’s take a look at the specific implementation method!
I am using Gin to create a REST API. The response I'm trying to create is a key value json map, for example:
"content": { "1.4.5.": { "id": "1.4.5.", "content": "some content", "title": "title" }, "1.4.6.": { "id": "1.4.6.", "content": "another content", "title": "another title" },
The data model I use is:
type TopicBundle struct { ... Content map[string]Topic `json:"content"` }
and it is correctly serialized to json:
c.JSON(200, topicBundle)
almost.
map[string]Topic never gets its values in the correct order. I create it from a sorted map. But this doesn't help.
var contentMap = make(map[string]Topic, sm.Len()) for _, key := range sm.Keys() { contentMap[key.(string)] = first(sm.Get(key)).(Topic) }
At some point this map appears to have been recreated and the order of the keys slightly changed. I can't think of any other alternatives, as Gin only seems to serialize this raw key-value map correctly. The sorted map from github.com/umpc/go-sortedmap is not serialized at all.
So how do I keep the order of the keys in this original (native?) structure? Or should I write a custom serializer for Gin?
I tried to find a solution on the internet.
My solution was to write a wrapper around sortedmap.SortedMap and write a custom MarshalJSON for this wrapper :
type TopicBundle struct { Content SortedMapWrapper `json:"content"` } type SortedMapWrapper struct { topics *sortedmap.SortedMap } func (wrapper SortedMapWrapper) MarshalJSON() ([]byte, error) { var sb strings.Builder var counter = 0 sb.WriteString("{") for _, key := range wrapper.topics.Keys() { sb.WriteString("\"") sb.WriteString(key.(string)) sb.WriteString("\":") sb.Write(first(json.Marshal(first(wrapper.topics.Get(key))))) counter += 1 if counter < wrapper.topics.Len() { sb.WriteString(",") } } sb.WriteString("}") return []byte(sb.String()), nil } func loadTopic(c *gin.Context) { var contentMap = sortedmap.New(1, comparisonFunc) contentMap.Insert("val1", Topic{"val1", "val2", "val3"}) contentMap.Insert("val33", Topic{"val1", "val2", "val3"}) var topicBundle = TopicBundle{} topicBundle.Content = SortedMapWrapper{contentMap} c.JSON(200, topicBundle) }
Please note that the definition of MarshalJSON should use SortedMapWrapper ( instead of *SortedMapWrapper). Otherwise it cannot be found.
The above is the detailed content of How to create a sorted key-value map that can be serialized to json by Gin?. For more information, please follow other related articles on the PHP Chinese website!