mongodb - Replacing ObjectId with embedded json when marshaling struct -


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 } 

playground

gives me:

json: {   "id": "postid001",   "title": "ima test",   "owner": {     "id": "ownerid002",     "name": "name ownerid002"   } } 

Comments