I was trying to create a go cookie. I want to assign Id from Mongodb to be stored in the Cookie. But while compiling I am getting an error as follows:-
"unknown http.Cookie field 'Id' in struct literal"
The following is my code:-
getUser := user.CheckDB()
expiration := time.Now().Add(365 * 24 * time.Hour)
//The Error is Caused by the Next Line
cookie := http.Cookie{Id: getUser[0].Id, Name: getUser[0].Email, Value: getUser[0].Password, Expires: expiration}
http.SetCookie(w, &cookie)
func (this *User) CheckDB() []User {
var results []User
sess, db := GetDatabase()
defer sess.Close()
c := db.C("user")
uname := &this.Email
err := c.Find(bson.M{"email": *uname}).Sort("-id").All(&results)
if err != nil {
panic(err)
} else {
fmt.Println("Results All: ", results)
return results
}
}
type Cookie struct {
Id bson.ObjectId `bson:"_id,omitempty"`
Name string
Value string
Path string
Domain string
Expires time.Time
RawExpires string
MaxAge int
Secure bool
HttpOnly bool
Raw string
Unparsed []string
}
Thanks in advance.
Here is a solution for this problem.
Cookie struct below:
type Cookie struct {
Name string
Value string
Path string
Domain string
Expires time.Time
RawExpires string
MaxAge int
Secure bool
HttpOnly bool
Raw string
Unparsed []string
}
Cookie Creation
value := map[string]string{
"id": cookieId,
}
if encoded, err := ckieHandler.Encode("session", value); err == nil {
cookie := &http.Cookie{
Name: "session",
Value: encoded,
Path: "/",
}
http.SetCookie(response, cookie)
}
Cookie Call
if cookie, err := request.Cookie("session"); err == nil {
cookieValue := make(map[string]string)
if err = ckieHandler.Decode("session", cookie.Value, &cookieValue); err == nil {
id = cookieValue["id"] // **Pass BSON ID here**
}
}
For more details Click Here. This link helped me a lot. Hoping someone will find this answer useful.
Related
When I send a POST request, the server does not receive the request body. Only the id is added to the database
"package lists
import (
"github.com/fishkaoff/fiber-todo-list/pkg/common/models"
"github.com/gofiber/fiber/v2"
)
type AddTaskRequestBody struct {
title string `json:"title"`
description string `json:"description"`
}
func (h handler) Addtask(c *fiber.Ctx) error {
body := AddTaskRequestBody{}
if err := c.BodyParser(&body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
title := body.title
description := body.title
if title == "" || description == "" {
return fiber.NewError(fiber.StatusBadRequest)
}
task := models.NewList(title, description)
if result := h.DB.Create(&task); result.Error != nil {
return fiber.NewError(fiber.StatusNotFound,
}
return c.Status(fiber.StatusCreated).JSON(&task)
}"
postman request:
enter image description here
the fields of the structure AddTaskRequestBody are not being exported. That may be the problem. Shouldn't title and description be uppercase - (https://golangbyexample.com/exported-unexported-fields-struct-go/)
type AddTaskRequestBody struct {
title string json:"title"
description string json:"description"
}
I am trying to write an email service, where I want to store some data related to email into a Postgres DB using gorm. I have a field which needs to be stored as a JSON blob, which in request passed as a JSON object. When I am trying to migrate, it errors keep saying unsupported type map. When manually add the DB, then run gorm, it doesn't write the row to the database.
I have seen some example where it's using postgres.Json as field types, but I want the field loaded from the request as map[string]string.
// Email : Base with injected fields `UUID`, `CreatedAt`, `UpdatedAt`
type Email struct {
gorm.Model
Status string `grom:"type:varchar(32);not null"`
TemplateID string `grom:"type:varchar(256)"`
ToEmai string `grom:"type:varchar(256);not null"`
FromEmail string `grom:"type:varchar(256);not null"`
ToName string `grom:"type:varchar(256);not null"`
FromName string `grom:"type:varchar(256);not null"`
Subject string `grom:"type:varchar(256)"`
Message string `grom:"type:varchar"`
DynamicData *map[string]string `grom:"type:json"`
}
this is my model.
then I do a gin request:
// SendEmail : sends an email
func SendEmail(c *gin.Context) {
body, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
log.Error("Error reading request body to get rate estimates")
}
var newEmail = models.Email{
Status: "PENDING",
}
jsonErr := json.Unmarshal(body, &newEmail)
if jsonErr != nil {
log.Error(jsonErr)
}
database.DB.Create(&newEmail)
defer c.Request.Body.Close()
err = newEmail.SendSendgridEmail()
if err != nil {
c.JSON(http.StatusBadRequest, err)
} else {
c.JSON(http.StatusOK, "Successfully sent email")
}
}
which then looks into this function
func (e Email) dynamicTemplateEmailBody() []byte {
newMail := mail.NewV3Mail()
emailFrom := mail.NewEmail(e.FromName, e.FromEmail)
newMail.SetFrom(emailFrom)
newMail.SetTemplateID(e.TemplateID)
p := mail.NewPersonalization()
tos := []*mail.Email{
mail.NewEmail(e.ToName, e.ToEmai),
}
p.AddTos(tos...)
if e.DynamicData != nil {
for key, value := range *e.DynamicData {
log.Infof("%s %s", key, value)
p.SetDynamicTemplateData(key, value)
}
}
newMail.AddPersonalizations(p)
return mail.GetRequestBody(newMail)
}
I would like to be able to run DB.AutoMigrate(&models.Email{}) and automatically migrate the objects, or and when I make a request to the endpoint, the row gets added to my email table.
I am trying to query using bison all JSON data in MongoDB with two fields but am getting null as result.
{
"allowedList": [
{
"List": [
{
"allow": {
"ss": 1,
},
"Information": [
{
"Id": "Id1"
}
]
}
]
}
]
}
I was able to filter all using the MongoDB at command line using
db.slicedb.find({"allowedList.List.allow.ss":1,"allowedList.List.Information.nsiId":"Id-Id21"})
but using
query := bson.M{"allowedList.List.allow": bson.M{"ss": sst}, "allowedList.List.Information": bson.M{"Id": Id}}
sst and Id are integer and string input to the query function
err := db.C(COLLECTION).Find(query).All(&specificSlices)
but is not working, am getting null even though there are json data that match the two field. Can someone help point out what was wrong with my query?
Server and database config
type SliceDataAccess struct {
Server string
Database string
}
var db *mgo.Database
const (
COLLECTION = "slicedb"
)
Establish a connection to database
func (m *SliceDataAccess) Connect() {
session, err := mgo.DialWithTimeout(m.Server, 20*time.Second)
if err != nil {
log.Fatal(err)
}
db = session.DB(m.Database)
}
Structs fields
type InstanceInfo struct {
ID string `json:"nfId" bson:"_id"`
AllowedList []AllowedNssai `json:"allowedList" bson:"allowedList"`
}
type AllowedNssai struct {
List []AllowedSnssai `json:"List,omitempty" bson:"List"`
...
}
type AllowedSnssai struct {
Allow *Snssai `json:"allow,omitempty" bson:"allow"`
Information []NsiInformation `json:"Information,omitempty" bson:"Information"`
}
type NsiInformation struct {
Id string `json:"Id" bson:"Id"`
}
type Snssai struct {
Ss int32 `json:"sst" bson:"ss"`
}
Query function defined
func (m *SliceDataAccess) FindAll(sst int32, nsiId string ([]InstanceInfo, error) {
var specificSlices []InstanceInfo
query := bson.M{"allowedList.List.allow": bson.M{"ss": sst}, "allowedList.List.Information": bson.M{"Id": nsiId}}
err := db.C(COLLECTION).Find(query).All(&specificSlices)
if err != nil {
return specificSlices, err
}
return specificSlices, nil
}
HTTP handler function for request and response
func AvailabilityGet(w http.ResponseWriter, r *http.Request)
var slice InstanceInfo
err := json.NewDecoder(r.Body).Decode(&slice)
if err != nil {
respondWithError(w, http.StatusBadRequest, "Object body not well decoded")
return
}
sst := slice.AllowedList[0].List[0].Allow.Sst
nsiId := slice.AllowedList[0].List[0].Information[0].Id
specificSlices, err := da.FindAll(sst, nsiId)
json.NewEncoder(w).Encode(specificSlices)
}
Attached is my the full go code i have done.
this worked
query := bson.M{"allowedNssaiList.allowedSnssaiList.allowedSnssai.sst": sst, "allowedNssaiList.allowedSnssaiList.nsiInformationList.nsiId": nsiId}
How do i query polls by id with go-gin and MongoDB, i have tried several methods but i still get errors (not found), can't seem to find a walk around below is my code, with my database on mongoDB:
type Poll struct {
//ID string `json:"_id,omitempty"`
ID bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"`
Firstname string `json:"firstname,omitempty"`
Lastname string `json:"lastname,omitempty"`
Poll string `json:"poll,omitempty"`
// Address *Address `json:"address,omitempty"`
}
var (
// Session stores mongo session
Session *mgo.Session
// Mongo stores the mongodb connection string information
Mongo *mgo.DialInfo
)
const (
// MongoDBUrl is the default mongodb url that will be used to connect to the
// database.
MongoDBUrl = "mongodb://localhost:27017/smartpoll"
// CollectionPoll holds the name of the poll collection
CollectionPoll = "polls"
)
// Connect connects to mongodb
func Connect() {
uri := os.Getenv("MONGODB_URL")
if len(uri) == 0 {
uri = MongoDBUrl
}
mongo, err := mgo.ParseURL(uri)
s, err := mgo.Dial(uri)
if err != nil {
fmt.Printf("Can't connect to mongo, go error %v\n", err)
panic(err.Error())
}
s.SetSafe(&mgo.Safe{})
fmt.Println("Connected to", uri)
Session = s
Mongo = mongo
}
func init() {
Connect()
}
func main() {
port := os.Getenv("PORT")
if port == "" {
log.Fatal("$PORT must be set")
}
router := gin.Default()
router.Use(ConnectMiddleware)
router.GET("/", func (c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "OK"})
})
router.GET("/polls/:_id", pollsByID)
router.Run(":" + port)
}
func ConnectMiddleware(c * gin.Context) {
c.Set("db", Session.DB(Mongo.Database))
c.Next()
}
func pollsByID(c * gin.Context) {
db := c.MustGet("db").(*mgo.Database)
id := c.Param("id")
poll := []Poll{}
// err := db.C(CollectionPoll).Find(id).One(&poll)
err := db.C(CollectionPoll).Find(bson.M{"_id": id}).One(&poll)
if err != nil {
//c.Error(err)
//panic(err)
log.Println(err)
}
result := gin.H{"payload": poll}
c.Writer.Header().Set("Content-Type", "application/json")
c.JSON(200, result)
}
my DB is as follows:
{
"_id" : ObjectId("58d9cf1cdf353f3d2f5951b4"),
"id" : "1",
"firstname" : "Sam",
"lastname" : "Smith",
"poll" : "Who is the Richest in the World"
}
Your ID is an ObjectId, but your input is a string. You need to use bson.ObjectIdHex to parse the string into an ObjectId:
err := db.C(CollectionPoll).FindId(bson.ObjectIdHex(id)).One(&poll)
Change polls from an array:
polls := []Poll{}
TO:
polls := Poll{}
I'm trying to code a simple web app in Go using Mongodb.
I've created a minimalistic simple Model / Controller setup.
I can create new user using POST with url "/user" with data such as '{"pseudo": "bobby1"}'. The user is created. However, when looking inside Mongodb shell, I get:
{ "_id" : ObjectId("5616d1ea56ca4dbc03bb83bc"), "id" : ObjectId("5616d1ea5213c64824000001"), "pseudo" : "bobby2"}
The "id" field is the one coming from my struct and the "_id" field is the one from Mongodb. From looking at different sample code, it looked like I could use myself the one from Mongodb but I can't find how to do it.. ><
Since the "id" is only used by me, I can't find user by their ID since I do not have that one...
More over, when I do a GET /user, it returns the full list of user, and I only get:
{"id":"5616d1ea5213c64824000001","pseudo":"bobby2"
Not the "real" Mongodb Id...
Thanks,
Here's the code:
model/user.go
const userCollection = "user"
// Get our collection
var C *mgo.Collection = database.GetCollection(userCollection)
// User represents the fields of a user in db
type User struct {
Id bson.ObjectId `json:"id"i bson:"_id,omitempty"`
Pseudo string `json:"pseudo" bson:"pseudo"`
}
// it will return every users in the db
func UserFindAll() []User {
var users []User
err := C.Find(bson.M{}).All(&users)
if err != nil {
panic(err)
}
return users
}
// UserFIndId return the user in the db with
// corresponding ID
func UserFindId(id string) User {
if !bson.IsObjectIdHex(id) {
s := fmt.Sprintf("Id given %s is not valid.", id)
panic(errors.New(s))
}
oid := bson.ObjectIdHex(id)
u := User{}
if err := C.FindId(oid).One(&u); err != nil {
panic(err)
}
return u
}
// UserCreate create a new user on the db
func UserCreate(u *User) {
u.Id = bson.NewObjectId()
err := C.Insert(u)
if err != nil {
panic(err)
}
}
controller/user.go
/ GetAll returns all users
func (us *UserController) GetAll(w http.ResponseWriter, request *http.Request) {
// u := model.User{
// ID: "987654321",
// Pseudo: "nikko",
// }
users := model.UserFindAll()
bu, err := json.Marshal(users)
if err != nil {
fmt.Printf("[-] Error while marshaling user struct : %v\n", err)
w.Write([]byte("Error Marshaling"))
w.WriteHeader(404)
return
}
w.Header().Set("Content-type", "application/json")
w.WriteHeader(200)
fmt.Fprintf(w, "%s\n", bu)
}
// Get return a specific user according to Id
func (us *UserController) Get(w http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
ps := vars["id"]
u := model.UserFindId(ps)
bu, err := json.Marshal(u)
if err != nil {
fmt.Printf("[-] Error while marshaling user struct : %v\n", err)
w.Write([]byte("Error Marshaling"))
w.WriteHeader(404)
return
}
w.Header().Set("Content-type", "application/json")
w.WriteHeader(200)
fmt.Fprintf(w, "%s\n", bu)
}
func (us *UserController) Post(w http.ResponseWriter, r *http.Request) {
u := model.User{}
json.NewDecoder(r.Body).Decode(&u)
model.UserCreate(&u)
bu, err := json.Marshal(u)
if err != nil {
fmt.Printf("[-] Error PUT user struct : %v\n", err)
w.WriteHeader(404)
return
}
w.Header().Set("Content-type", "application/json")
w.WriteHeader(201)
fmt.Fprintf(w, "%s\n", bu)
}
Looks like you have a stray character in your struct tags:
type User struct {
Id bson.ObjectId `json:"id"i bson:"_id,omitempty"`
Pseudo string `json:"pseudo" bson:"pseudo"`
}
That i should not exist after json:"id". It should be:
type User struct {
Id bson.ObjectId `json:"id" bson:"_id,omitempty"`
Pseudo string `json:"pseudo" bson:"pseudo"`
}