Go を使用して基本的な API を構築し、postgres テーブルの JSON フィールドに JSON を他の (プレーンな) データ型と共に格納しました。私のモデルを使用して、単純にデータベースから行をフェッチし、それを JSON として転送しようとしています。
GORMを使用してデータを構造体に逆シリアル化すると、選択したデータ型に応じてバイト配列または文字列としてレンダリングされる JSON を除いて、ほとんどのマッピングがシームレスに行われます。
モデルは次のとおりです(更新済み):
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"`
}
典型的な JSON は次のようになります (DB から):
[{"stat": "Multistrike", "amount": 193}, {"stat": "Crit", "amount": 145},
{"stat": "Agility", "amount": 254}, {"stat": "Stamina", "amount": 381}]
したがって、このデータを変更したり、Go 構造体などに逆シリアル化したりするのではなく、単にこのデータを渡したいという考えです。コントローラー/ルートは次のとおりです。
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)
}
}
次の JSON で応答します (統計は json.RawMessage として):
{
"context": "raid-finder",
"stats": "W3sic3RhdCI6ICJWZXJzYXRpbGl0eSIsICJhbW91bnQiOiA0NX0sIHsic3RhdCI6ICJDcml0IiwgImFtb3VudCI6IDEwMH0sIHsic3RhdCI6ICJBZ2lsaXR5IiwgImFtb3VudCI6IDEwOX0sIHsic3RhdCI6ICJTdGFtaW5hIiwgImFtb3VudCI6IDE2M31d",
}
または、代わりに (統計を文字列として):
{
"context": "raid-finder",
"stats": "[{\"stat\": \"Versatility\", \"amount\": 45}, {\"stat\": \"Crit\", \"amount\": 100}, {\"stat\": \"Agility\", \"amount\": 109}, {\"stat\": \"Stamina\", \"amount\": 163}]",
}
これを単純に渡すために必要なオプションは何ですか?これまでのところ、JSON を構造体にマップしようとして失敗しました (動的データと、最初に JSON を選択した理由により、これは困難になります)。
c.JSONが構造体から JSON にすべてのデータを自動的にマーシャリングすることで、 gin-gonicからいくつかの魔法が起こっていることに気付きましたが、json データのマーシャリングを回避する方法があることを望んでいますか?
ItemInfo サブ構造体で実行すると、次のエラーでパニックになります。
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)
編集:更新されたコード: