Anachunam Michael
Anachunam Michael

Reputation: 33

how to use struct pointers in golang

I am trying to do a simple golang with gin post and get request, every other thing works just fine, apart from the part that the values that are supposed to be in the struct variables are empty, the example is bellow if i didnt explain well my code(main)

package main

import (
    //"fmt"
    "github.com/cosimmichael/assessment/app/db_client"
    "github.com/cosimmichael/assessment/app/controllers"
    "github.com/gin-gonic/gin"
    // you need to import go mod  init for this parkage to work
    // "github.com/cosimmichael/assessment/app/strutil"
    // "github.com/cosimmichael/assessment/app/routers"
    // "net/http"
)

func main(){
    db_client.InitialiseDBConnection()

    r := gin.Default()

    r.POST("api/v1/products/create", controller.CreateProducts)
    r.GET("api/v1/products/{product_id}/show", controller.GetPosts)

    if err := r.Run(":3000"); err != nil {
        panic(err.Error())
    }
    // router.HandleRoutes()
    // fmt.Println("Server Starting.. @ port :3000")
    // http.ListenAndServe(":3000", nil)
}

my code (controller)

package controller

import (
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/cosimmichael/assessment/app/db_client"
    // "fmt"
)

type Post struct {
    id int64            `json: "id"`
    title *string       `json: "title"`
    description *string     `json: "description"`
}

func CreateProducts(c *gin.Context) {
    var reqBody Post
    if err := c.ShouldBindJSON(&reqBody); err != nil {
        c.JSON(http.StatusUnprocessableEntity, gin.H{
            "error": true,
            "message": "Invalid request body",
        })
        return
    }

    res, err := db_client.DBClient.Exec("INSERT INTO products (title, description) VALUES (?, ?);", 
        reqBody.title,//"testing",
        reqBody.description,//"Just testing something",
    )
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{
            "error": true,
            "message": "Invalid request body2",
        })
        return
    }

    id, err := res.LastInsertId()
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{
            "error": true,
            "message": "Invalid request body3",
        })
        return
    }

    c.JSON(http.StatusCreated, gin.H{
        "error": false,
        "id": id,
    })
}

func GetPosts(c *gin.Context){
    var posts []Post

    rows, err := db_client.DBClient.Query("SELECT id, title, description FROM products;")
    if err != nil {
        c.JSON(http.StatusUnprocessableEntity, gin.H{
            "error": true,
            "message": "Invalid request body",
        })
        return
    }

    for rows.Next(){
        var singlePost Post
        if err := rows.Scan(&singlePost.id, &singlePost.title, &singlePost.description); err != nil {
            c.JSON(http.StatusUnprocessableEntity, gin.H{
                "error": true,
                "message": "Invalid request body",
            })
            return
        }
        posts = append(posts, singlePost)
    }

    c.JSON(http.StatusOK, rows)
}


my code db_client

package db_client

import (
    "database/sql"
    //"time"
    _ "github.com/go-sql-driver/mysql"
)

var DBClient *sql.DB

func InitialiseDBConnection(){
    //[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
    db, err := sql.Open("mysql","root:2580@tcp(localhost:3306)/grabit?parseTime=true")
    if err != nil {
        panic(err.Error())
    }
    err = db.Ping()
    if err != nil {
        panic(err.Error())
    }

    DBClient = db
}

now when I use postman insert new row, it inserts an empty row with only id, no title nor description, when i try fetching, i get an empty array, please what is the problem, i am new to golang

Upvotes: 0

Views: 326

Answers (3)

rTom
rTom

Reputation: 11

Using Structs

If a field or method name starts with a capital letter, the member is exported and is accessible outside of the package.

If a field or method starts with a lowercase letter, the member is unexported and does not have accessibility outside of the package.

Note: The Inorder to do the operations like Marshalling Un-marshalling etc in golang json package you need to have field names should start with uppercase letters. Because it uses reflection inside to process.

Upvotes: 1

uPong
uPong

Reputation: 29

Need to use a capitalise letter because if you don't use it you can only see in the same package.

Capitalise letter = see in all package

Normal letter = see only in same package (for example: controller only here)

Upvotes: 1

dpthegrey
dpthegrey

Reputation: 157

you need to capitalise the first character of values inside struct field.

For Example:

type Book struct {
  ID     uint   `json:"id" gorm:"primary_key"`
  Title  string `json:"title"`
  Author string `json:"author"`
}

Upvotes: 1

Related Questions