from the example looks like we can only return a single json file for response? could you please advice? thanks
Context.JSON accepts an interface{} which means that you can pass any value.
res := []string{"foo", "bar"}
c.JSON(200, res)
Has the expected result:
["foo","bar"]
@alexandernyquist is right.
Check this out: http://golang.org/pkg/encoding/json/
Context.JSON uses it
For context.JSON supporting slice of nested structs
type Tag struct {
Name string `json:"name" form:"name" binding:"required"`
Description string `json:"description" form:"description" binding:"required"`
ExtraData TagExtra `json:"extra"`
}
tags := getTags() // which return []Tag
c.JSON(200, tags)
in result ExtraData looks empty even though ExtraData exist
[
{
"name": "question",
"description": "question is something cool",
"extra": {}
},
{
"name": "intro",
"description": "intro is something cool",
"extra": {}
},
...
]
when assigning to an interface slice everything seems to work out.
type Tag struct {
Name string `json:"name" form:"name" binding:"required"`
Description string `json:"description" form:"description" binding:"required"`
ExtraData TagExtra `json:"extra"`
}
tags := getTags() // which return []Tag
var interfaceSlice []interface{} = make([]interface{}, len(tags))
for i, tag := range tags {
interfaceSlice[i] = tag
}
c.JSON(200, interfaceSlice)
[
{
"name": "question",
"description": "question is something cool",
"extra":
{
"id": 1,
"created_at": "2015-08-25T00:35:55.408537Z"
...
},
...
]
For now i'm reassigning to interfaceslice. Is there a better way to do this?
@thellimist
Try taking your []Tag slice and converting it to a []byte slice and write
it manually like this (you need to import "encoding/json"):
byteSlice,err := json.Marshal(yourSlice)
if err != nil {
panic(err)
}
c.Writer.Header().Set("Content-Type","application/json")
c.Writer.WriteHeader(200)
c.Writer.Write(byteSlice)
Can you see ExtraData in the json output if you do it this way? Do you get
an error at all? Maybe this can give you some more insight as to how your
Struct is being misinterpreted by gins c.JSON function.
You say, "nested arrays", but it looks like ExtraData is just a dictionary, make sure you are using a slice to hold the data that is inside ExtraData (eg. []TagExtra) if you want an array.
Lastly, you don't want to display ExtraData if its empty, but you are sacrificing your output fieldname to do so. The "encoding/json" package allows you to double up with the omitempty option like so: json:"myName,omitempty"
On Mon, Aug 24, 2015 at 3:26 PM, Furkan Yilmaz [email protected]
wrote:
type Tag struct {
Name stringjson:"name" form:"name" binding:"required"
Description stringjson:"description" form:"description" binding:"required"
ExtraData TagExtrajson:"extra"
}tags := getTags() // which return []Tag
c.JSON(200, tags)
results is although ExtraData exist
[
{
"name": "question",
"description": "question is something cool",
"ExtraData": {}
},
{
"name": "intro",
"description": "intro is something cool",
"ExtraData": {}
},
...
]when assigning to an interface slice everything seems to work out.
type Tag struct {
Name stringjson:"name" form:"name" binding:"required"
Description stringjson:"description" form:"description" binding:"required"
ExtraData TagExtrajson:"extra"
}tags := getTags() // which return []Tag
var interfaceSlice []interface{} = make([]interface{}, len(tags))
for i, tag := range tags {
interfaceSlice[i] = tag
}c.JSON(200, interfaceSlice)
[
{
"name": "question",
"description": "question is something cool",
"ExtraData":
{
"id": 1,
"created_at": "2015-08-25T00:35:55.408537Z"
...
},
...
]—
Reply to this email directly or view it on GitHub
https://github.com/gin-gonic/gin/issues/87#issuecomment-134399364.
@TheRealKira
byteSlice,err := json.Marshal(yourSlice)
if err != nil {
panic(err)
}
c.Writer.Header().Set("Content-Type","application/json")
c.Writer.WriteHeader(200)
c.Writer.Write(byteSlice)
this doesn't work.
You say, "nested arrays"..
I meant "slice of nested structs" sorry for that misunderstanding. Edited the comment
@thellimist could you post the code for your getTags() function? I'm trying to figure out where in your Extra struct the non interface type screws with encoding/json.
When you said array I knew you meant slice, I just wanted to make sure you were storing a slice []ExtraData and not just ExtraData in your top level struct.
@TheRealKira
type Tag struct {
Name string `json:"name" form:"name" binding:"required"`
Description string `json:"description" form:"description" binding:"required"`
ExtraData TagExtra `json:"extra"`
}
type TagExtra struct {
TypeInformation TypeInformation `json:"type_information"`
SenderUser User `json:"sender_user"`
}
and getTags returns []Tag. The inner struct (TagExtra) screws encoding/json somehow.
tags := getTags()
var interfaceSlice []interface{} = make([]interface{}, len(tags))
for i, tag := range tags {
interfaceSlice[i] = tag
}
c.JSON(200, tags[0]) // returns TagExtra's information correctly
c.JSON(200, tags) // returns TagExtra's information empty
c.JSON(200, interfaceSlice) // returns TagExtra's information correctly
So expected result will be something like
[
{
"name": "question",
"description": "question is something cool",
"extra":
{
"type_information":
{
...
},
"sender_user":
{
...
}
}
},
...
]
but instead it returns
[
{
"name": "question",
"description": "question is something cool",
"extra": {}
},
...
]
I hope I was able to clarify. Thank you.
@TheRealKira
byteSlice,err := json.Marshal(yourSlice) if err != nil { panic(err) } c.Writer.Header().Set("Content-Type","application/json") c.Writer.WriteHeader(200) c.Writer.Write(byteSlice)this doesn't work.
You say, "nested arrays"..
I meant "slice of nested structs" sorry for that misunderstanding. Edited the comment
I also want to know how to response that string as json.
Most helpful comment
Context.JSONaccepts aninterface{}which means that you can pass any value.Has the expected result: