My goal is to implement this code. Except instead of using sql I want to use mongoDB. I think there is an issue with how I handle my sessions.
I'm trying to use mgo to insert some user data into MongoDB via a Rest API. Whenever I open the mongo shell and run the show dbs
command, the poll
DB is not displayed. I'm using Postman to test the Rest API. Any ideas what am I might be doing wrong in the insertion process? I tried creating the collection first in the mongo shell and then running the CreateUser
function but I still didnt see the poll
DB get created.
User
type User struct {
Id bson.ObjectId `json:"id" bson:"_id,omitempty"`
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
}
UserDAO
type UserDAO struct {
session *mgo.Session
}
Creating a session
func GetMongoSession() *mgo.Session {
if mgoSession == nil {
var err error
mgoSession, err = mgo.Dial("localhost")
mgoSession.SetMode(mgo.Monotonic, true)
if err != nil {
log.Fatal("Failed to start the Mongo session.")
}
}
return mgoSession.Clone()
}
I pass a User struct into the CreateUser
function that I create using Postman:
{
"username":"uname",
"password":"pass",
"email":"test@mail.com"
}
Then I just respond with the same struct and receive this output:
{
"id": "",
"username": "uname",
"password": "pass",
"email": "test@mail.com"
}
Creating a user
func (dao *UserDAO) CreateUser(u *User) (*User, error) {
//return errors.New("Not implemented")
// Get "users" collection
dao.session = GetMongoSession()
c := dao.session.DB("poll").C("user")
defer dao.session.Close()
//u.Id = bson.NewObjectId()
err := c.Insert(u)
if err != nil {
return nil, err
}
return u, nil
}
Http handler function
func (h *Handler) CreateUserReq(w http.ResponseWriter, r *http.Request) {
// create new user using information from the Request object
var user User
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&user); err != nil {
panic(err)
}
defer r.Body.Close()
// Create new User
u, err := h.UserService.CreateUser(&user)
if err != nil {
panic(err)
}
json.NewEncoder(w).Encode(*u)
}
Output of show dbs
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
Try below code and first of all I check is my user struct contains data coming from postman and then there is one error also when you are assigning the session *mgo.Session
to non-pointer dao.session
variable. So I have changed many a things and it is working fine creating both database with poll
name and creating a user collection with new document also I have removed ObjectId from User struct. Check it out
package main
import (
"encoding/json"
"gopkg.in/mgo.v2"
"log"
// "gopkg.in/mgo.v2/bson"
)
var (
mgoSession *mgo.Session
)
type UserDAO struct{
session *mgo.Session
}
type User struct {
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
}
func GetMongoSession() *mgo.Session {
if mgoSession == nil {
var err error
mgoSession, err = mgo.Dial("localhost")
mgoSession.SetMode(mgo.Monotonic, true)
if err != nil {
log.Fatal("Failed to start the Mongo session.")
}
}
return mgoSession.Clone()
}
func (dao *UserDAO) CreateUser(u *User) (*User, error) {
//return errors.New("Not implemented")
// Get "users" collection
session := GetMongoSession()
// log.Println(session)
c := session.DB("poll").C("user")
defer session.Close()
//u.Id = bson.NewObjectId()
err := c.Insert(u)
if err != nil {
return nil, err
}
return u, nil
}
func main(){
// this data will come from postman in your case
jsonStr := []byte(`{
"username":"uname",
"password":"pass",
"email":"test@mail.com"
}
`)
var user User
err := json.Unmarshal(jsonStr, &user)
if err != nil{
log.Println(err)
}
var dao *UserDAO
dao.CreateUser(&user)
}
My collection output is:-
{
"_id" : ObjectId("5a80993f32fcc2489f995aaf"),
"username" : "uname",
"password" : "pass",
"email" : "test@mail.com"
}
you don't need to create a Object id for new document it will be created itself when inserting a new document. Also If you wants top just create a collection using golang and then insert data you can create it explicitly. Go through this function create collection
Since, I don't have full context of your application so can't diagnose what exactly issue is with your code. But I came up with close example, which is working as expected.
Please see code below.
package main
import (
"gopkg.in/mgo.v2"
"log"
"gopkg.in/mgo.v2/bson"
)
type User struct {
Id bson.ObjectId `json:"id" bson:"_id,omitempty"`
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
}
func GetMongoSession() *mgo.Session {
mgoSession, err := mgo.Dial("localhost")
mgoSession.SetMode(mgo.Monotonic, true)
if err != nil {
log.Fatal("Failed to start the Mongo session.")
}
return mgoSession.Clone()
}
func CreateUser(u *User) (*User, error) {
session := GetMongoSession()
c := session.DB("poll").C("user")
defer session.Close()
err := c.Insert(u)
if err != nil {
return nil, err
}
return u, nil
}
func main() {
var user = User{
Email: "abc@somewhere.come",
Password: "My-secret",
Username: "YouGuess",
}
_, e := CreateUser(&user)
if e != nil {
panic(e)
}
log.Println("Done...")
}
once you execute it, you should see a document in MongoDB provided that you successfully establish connection with proper credentials.
I can see following document in my collection:
{
"_id": ObjectId("5a80941de0a0f75123aeb435"),
"username": "YouGuess",
"password": "My-secret",
"email": "abc@somewhere.come"
}