Création d'une API de base avec Go, j'ai JSON stocké dans un champ JSON dans une table postgres, avec quelques autres types de données (simples). À l'aide de mon modèle, j'essaie simplement d'extraire une ligne de la base de données et de la transmettre en tant que JSON.Désérialisation de JSON imbriqué, ou simplement transfert dans Go
En utilisant GORM pour désérialiser les données dans une structure, la plus grande partie du mappage se produit de manière transparente, à l'exception du JSON qui, selon le type de données sélectionné, se traduit par un bytearray ou une chaîne.
Voici les modèles (Mise à jour):
type Item struct {
--snip--
Stats []ItemInfo `gorm:"column:stats" json:"stats" sql:"json"`
--snip--
}
type ItemInfo struct {
Stat string `json:"stat"`
Amount int `json:"amount"`
}
Avec le JSON typique qui ressemble à ceci (à partir du DB):
[{"stat": "Multistrike", "amount": 193}, {"stat": "Crit", "amount": 145},
{"stat": "Agility", "amount": 254}, {"stat": "Stamina", "amount": 381}]
L'idée est que je veux simplement passer ce données sur, ne pas le modifier, ou désérialiser à une structure Go ou quoi que ce soit. Le contrôleur suit/route:
func GetItem(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
// Convert Parameter to int, for db query
if err != nil {
panic(err)
}
// Get the DB context
db, ok := c.MustGet("databaseConnection").(gorm.DB)
if !ok {
// Do something
}
// Hold the structified item here.
var returnedItem models.Item
// Get the db row
db.Where(&models.Item{ItemID: id}).First(&returnedItem)
if c.Bind(&returnedItem) == nil {
// Respond with the struct as json
c.JSON(http.StatusOK, returnedItem)
}
}
qui répond à la JSON suivante (avec statistiques comme json.RawMessage):
{
"context": "raid-finder",
"stats": "W3sic3RhdCI6ICJWZXJzYXRpbGl0eSIsICJhbW91bnQiOiA0NX0sIHsic3RhdCI6ICJDcml0IiwgImFtb3VudCI6IDEwMH0sIHsic3RhdCI6ICJBZ2lsaXR5IiwgImFtb3VudCI6IDEwOX0sIHsic3RhdCI6ICJTdGFtaW5hIiwgImFtb3VudCI6IDE2M31d",
}
Ou bien (avec des statistiques comme chaîne):
{
"context": "raid-finder",
"stats": "[{\"stat\": \"Versatility\", \"amount\": 45}, {\"stat\": \"Crit\", \"amount\": 100}, {\"stat\": \"Agility\", \"amount\": 109}, {\"stat\": \"Stamina\", \"amount\": 163}]",
}
De quelles options ai-je besoin pour simplement transmettre ceci, jusqu'ici j'ai essayé sans succès de mapper le JSON à un struct (qui devient difficile à cause des données dynamiques, et la raison pour laquelle j'ai choisi JSON pour commencer)?
Je me rends compte qu'il y a de la magie à partir de gin-gonic, avec c.JSON automatiquement (?) Rassemblant toutes les données de la structure en JSON, mais en espérant qu'il y ait un moyen d'éviter de rassembler les données json?
Quand couru avec le substruct itemInfo, il affole avec l'erreur suivante:
2016/01/07 08:21:08 Panic recovery -> reflect.Set: value of type []uint8 is not assignable to type []models.ItemInfo
/usr/local/go/src/runtime/panic.go:423 (0x42a929)
gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/usr/local/go/src/reflect/value.go:2158 (0x5492ce)
Value.assignTo: panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
/usr/local/go/src/reflect/value.go:1327 (0x546195)
EDIT: Code Mise à jour:
Pourrait fournir une réponse complète plus tard, mais ma suggestion est assez simple, ajouter un champ supplémentaire à votre type pour représenter le json comme un [] octet, laissez GORM unmarshal dans cela. Après cela, utilisez 'encoding/json' pour démélanger le' [] byte' dans la structure cible. – evanmcdonnal
Je me sens mal parce que j'ai manqué votre commentaire, et il s'est avéré être une solution super facile. Merci beaucoup! –