Home  >  Article  >  Backend Development  >  How to create a sorted key-value map that can be serialized to json by Gin?

How to create a sorted key-value map that can be serialized to json by Gin?

WBOY
WBOYforward
2024-02-08 23:36:10726browse

如何创建一个可以由 Gin 序列化为 json 的排序键值映射?

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!

Question content

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.

Solution

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete