i'm building restful api go , mongodb, , i'm running difficulty embedding json 1 document inside json another. here's toy example of i'm trying accomplish. have following schemas:
type post struct { id bson.objectid `json:"id,omitempty"` title string `json:"title,omitempty"` owner bson.objectid `json:"owner,omitempty"` // references user } type user struct { id bson.objectid `json:"id,omitempty"` name string `json:"name,omitempty"` }
when creating json post, i'd first owner of post in mongodb , embed resulting user inside said post's json (in-place of original objectid
), so:
{ "id": "...", "title": "my awesome post", "owner": { "id": "...", "name": "cody" } }
i'm not quite sure how accomplish this, other manually constructing json using map[string]interface{}
, so:
post := lookuppost(...) user := lookupuser(post.owner) m := map[string]interface{}{ "id": post.id, "title": post.title, "owner": map[string]interface{}{ "id": user.id, "name": user.name, }, } b, _ := json.marshal(m)
obviously doesn't scale well isn't dry -- ideally, i'd able utilize json
tags in each struct definition , have fields inserted automatically.
am missing something, or i'm trying impossible? or not approaching mongodb/json in go correctly? put things in perspective, i'm coming node.js background, sort of functionality trivial.
edit
to clarify things, here's incorrect go code shows i'd do
func getpostjson() []byte { p := lookuppost(...) u := lookupuser(p.owner, ...) uj, _ := json.marshal(u) p.owner = uj // can't in go pj, _ := json.marshal(p) return pj }
i'm not familar mongodb or bson.objectid
, can substitute own type user
field , have mongodb fill in user's bson.objectid
?
if can wrap user object id's own type implements json.marshaler
interface. e.g.:
// embedded (instead of `type x bson.objectid`) // methods , satisfy interfaces // bson.objectid does. that's engough allow mongodb // fill in fields of type database?? type ownerobjid struct{ bson.objectid } // here marshal results of looking user id // rather id itself. func (oid ownerobjid) marshaljson() ([]byte, error) { user, err := lookupuser(oid.objectid) if err != nil { return nil, err } return json.marshal(user) } type post struct { id bson.objectid `json:"id,omitempty"` title string `json:"title,omitempty"` owner ownerobjid `json:"owner,omitempty"` // <-- type wrapping doable/easy mongodb? } type user struct { id bson.objectid `json:"id,omitempty"` name string `json:"name,omitempty"` } func main() { post := lookuppost() b, err := json.marshalindent(post, "", " ") if err != nil { log.fatal(err) } fmt.printf("json:\n%s\n", b) } // stubs demo: func lookuppost() post { return post{ id: "postid001", title: "ima test", owner: ownerobjid{"ownerid002"}, } } func lookupuser(id bson.objectid) (user, error) { return user{ id: id, name: "name " + string(id), }, nil }
gives me:
json: { "id": "postid001", "title": "ima test", "owner": { "id": "ownerid002", "name": "name ownerid002" } }
Comments
Post a Comment