Hi I’m very new to learn jin framework. I’m trying to creating POST api with on that.
How do I make conditional statement in jin framework?
Currently I’ve got 2 optional values in JSON body(startDate, endDate)
I’d like to using those 2 values in conditional statement for diverting.
(Like if I’ve got startDate execute “logic 1” or got endDate execute “logic 2”)
Here is the code down below. How can I divert optional values in jin framework?
type StartEndDate struct {
StartDate string `json:startdate`
EndDate string `json:enddate`
}
func CheckSomething(c *gin.Context) {
var data StartEndDate
err := json.NewDecoder(c.Request.Body).Decode(&data)
if err != nil {
fmt.Println(err)
}
if data.StartDate != nil {
// if StatDate in body ~~~
}
if data.EndDate != nil {
// if EndDate in body~~~
}
Related
I need to get one param from posted json.
And I don't want to make struct for only this.
This is what I have tried
type NewTask struct {
Price uint64 `json:"price"`
}
func (pc TaskController) Create(c *gin.Context) {
var service Service
if err := c.BindJSON(&service); err != nil {
log.Println(err) // this works
}
var u NewTask
if err := c.BindJSON(&u); err != nil {
log.Println(err) // this return EOF error
}
fmt.Println(u.Price)
}
Requested Json data have many other fields including price
{
...other fields
price: 30
}
But this don't work.I think its because I am binding twice, How can I success in binding multiple?
Thanks
Try to use ShouldBindJSON. The BindJSON is reading the body, so we are at EOF if the context Body get read multiple times.
ShouldBindJSON stores the request body into the context, and reuse when it is called again.
I'm creating a rest api in golang and making a POST request into a table.
For this I've created a struct. Basically the vars in struct is same as the columns in table named users.
and written a function to make a POST request. And the code is working fine, the params while making POST request is being inserted successfully in the table.
type User struct {
ID int
Name string
Lname string
Country string
}
func insertUser(response http.ResponseWriter, request *http.Request)
{
var userDetails User
decoder := json.NewDecoder(request.Body)
err := decoder.Decode(&userDetails)
defer request.Body.Close()
if err != nil {
returnErrorResponse(response,request, httpError)
} else {
httpError.Code = http.StatusBadRequest
if userDetails.Name == "" {
httpError.Message = "first name can't be empty"
returnErrorResponse(response, request, httpError)
} else if userDetails.Lname == "" {
httpError.Message = "Last name can't be empty"
returnErrorResponse(response, request, httpError)
} else {
isInserted := insertUserInDB(userDetails)
if isInserted {
getAllUsers(response, request)
} else {
returnErrorResponse(response, request, httpError)
}
}
}
}
Here is insertUserInDB(userDetails) definition
func insertUserInDB(userDetails User) bool {
stmt, err := db.Prepare("insert into users set Name=?, Lname=?,
Country=?")
if err != nil {
fmt.Print("helper_methods.go : 118")
fmt.Println(err)
return false
}
_, queryError := stmt.Exec(tableName, userDetails.Name,
userDetails.Lname, userDetails.Country)
if queryError != nil {
fmt.Print("helper_methods.go : 125")
fmt.Println(queryError)
return false
}
return true
}
Is there any way to write a common function to insert record in any of the table in the DB?
Can we create struct dynamically, or any other way?
Please help me out here.
Like in other languages, you can use an ORM library to do the DB translation for you, for example GORM, or you can do the translation yourself. Since you already implemented saving the data manually, see this article for how to retrieve data manually.
If you just want to write a generic method that generates/executes SQL queries by matching struct field names you can use the reflect package of go. You will have to identify the structs fields by using reflect.TypeOf() to get the Type of your passed variable and then iterate over the StructField that you can get by using the Field() method on the Type. The StructField will reveal the Name and ValueOf() will allow you to access the Value. Name and value can then be used to construct the query.
For getting a better understanding I recommend you read some articles on reflect. Like this and this.
I think you can use package Refleciton in Golang
,at first step you have to create a method that generates a query for any given type
of struct, for example i write a method that generates an insert query for given
struct.
I have thus two type
type FirstType struct {
FirstParam string
SecondParam int
}
type SecondType struct {
FirstParam string
SecondParam string
ThirdParam int
}
My insert query generation method is as follow
func generateInsetMethod(input inrerface{}) (string, error) {
if reflect.ValueOf(q).Kind() == reflect.Struct {
query := fmt.Sprintf("insert into %s values(", reflect.TypeOf(q).Name())
v := reflect.ValueOf(q)
for i := 0; i < v.NumField(); i++ {
switch v.Field(i).Kind() {
case reflect.Int:
if i == 0 {
query = fmt.Sprintf("%s%d", query, v.Field(i).Int())
} else {
query = fmt.Sprintf("%s, %d", query, v.Field(i).Int())
}
case reflect.String:
if i == 0 {
query = fmt.Sprintf("%s\"%s\"", query, v.Field(i).String())
} else {
query = fmt.Sprintf("%s, \"%s\"", query, v.Field(i).String())
}
default:
fmt.Println("Unsupported type")
}
}
query = fmt.Sprintf("%s)", query)
return query, nil
}
return ``, QueryGenerationError{}
}
know you can use this function to generate your insert queries and also you can generate other functions for Update and etch query that you wants
I've got a Golang Website where I want to display 'scores' from my UWP Game using SQLite's Mobile App Quickstart's API called SwaggerUI. I am getting the scores by doing a HTTP GET request. The problem is that the scores output to the Golang console in JSON Format. I want to display the scores onto the actual website. How could I call my golang function in the Frontend in order to do this? The frontend is written in HTML/Javascript/JQuery.
This is my Golang Function that does the HTTP Request to SwaggerUI and outputs to the Golang Console:
func scoresPage(res http.ResponseWriter, req *http.Request) {
//Connecting to SwaggerUI API to get Scores from Azure for UWP Application
req, err := http.NewRequest("GET", os.ExpandEnv("https://brainworksappservice.azurewebsites.net/tables/TodoItem?$select=score"), nil)
if err != nil {
log.Fatal(err)
}
//You have to specify these headers
req.Header.Set("Accept", "application/json")
//If you do not specify what version your API is, you cannot receive the JSON
req.Header.Set("Zumo-Api-Version", "2.0.0")
//Do the request
resp, err := http.DefaultClient.Do(req)
//Error if the request cannot be done
if err != nil {
log.Fatal(err)
}
//You need to close the Body everytime, as if you don't you could leak information
defer resp.Body.Close()
//Read all of the information from the body
body, err := ioutil.ReadAll(resp.Body)
//Error if the info cannot be read
if err != nil {
log.Fatal(err)
}
//Write the JSON to the standard output (the Console)
_, err = os.Stdout.Write(body)
//Error if the info cannot be output to the console
if err != nil {
log.Fatal(err)
}
http.ServeFile(res, req, "Scores.html")
} `
This is the main Function which serves up the website and handles the scores page:
func main() {
http.HandleFunc("/scores", scoresPage)
//serve on the port 8000 forever
http.ListenAndServe(":8000", nil)
}
Assuming, that you don't want to dump the json as is onto you page but instead format it in some way with html and css, then you could first decode the returned body into a slice of structs that mirror the structure of your json. For example like this:
type Score struct {
Id string `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Version string `json:"version"`
Deleted bool `json:"deleted"`
Text string `json:"text"`
Complete bool `json:"complete"`
Score string `json:"score"`
}
scores := []*Score{}
if err := json.Unmarshal(body, &scores); err != nil {
panic(err)
}
fmt.Println(scores[0])
https://play.golang.org/p/m_ySdZulqy
After you've decoded the json you can use Go's template package to loop over the scores and format them as you wish. While you should use the html/template package for rendering html you should check out text/template for the documentation on how to actually program the templates, they have the same interface.
Here's a quick example: https://play.golang.org/p/EYfV-TzoA0
In that example I'm using the template package to parse a string (scoresPage) and output the result to stdout, but you can just as easily parse your Scores.html file with ParseFiles and return the output in the http response by passing the res http.ResponseWriter instead of os.Stdout as the first argument to template.Execute.
Coming from languages like Python, Ruby, and JS, I am really struggling with Go right now. It feels overly complex, but I am hoping I am just missing something.
Right now I have code that can successfully call Boston's MBTA API (using their public developer key) and return all route information.
I have dropped the code here: http://pastebin.com/PkBaP714 and here: http://pastebin.com/7mRxgrpp
Sample data returned: http://pastebin.com/M2hzMKYs
I want to return two things 1) JUST each route_type and mode_name, and 2) when route_type is called each of the route_id and route_name.
For whatever reason I am just totally lost. I've spent 16 hours staring at documentation and I feel like I am looking at a foreign language :).
It may be too much to ask for specific help, but I would LOVE IT.
Just map them to a new type:
func main() {
flag.Parse()
c := gombta.Client{APIKey: apikey, URL: apiurl}
// get a list of routes by type
d, err := c.GetRoutes(format)
check(err)
var toPrint interface{}
if typeid == 9999 {
type Result struct {
RouteType string `json:"route_type"`
ModeName string `json:"mode_name"`
}
rs := []Result{}
for _, m := range d.Mode {
rs = append(rs, Result{
RouteType: m.RouteType,
ModeName: m.ModeName,
})
}
toPrint = rs
} else {
type Result struct {
RouteID string `json:"route_id"`
RouteName string `json:"route_name"`
}
rs := []Result{}
for _, m := range d.Mode {
if fmt.Sprint(typeid) == m.RouteType {
for _, r := range m.Route {
rs = append(rs, Result{
RouteID: r.RouteID,
RouteName: r.RouteName,
})
}
}
}
toPrint = rs
}
j, err := json.MarshalIndent(toPrint, "", " ")
fmt.Printf("RouteTypes: ")
os.Stdout.Write(j)
}
first off let me say I'm a beginner (started a few days ago) with golang and am in the process of learning how to practically apply the language. My goal is to build a web Rest API that queries a database and provides data back to the user.
I've been able to successfully create a simple API using martini (https://github.com/go-martini/martini) and connect to a MySQL database using https://github.com/go-sql-driver/mysql. My problem at the current moment is how to pass a variable param from the API request into my query. Here is my current code:
package main
import (
"github.com/go-martini/martini"
_ "github.com/go-sql-driver/mysql"
"database/sql"
"fmt"
)
func main() {
db, err := sql.Open("mysql",
"root:root#tcp(localhost:8889)/test")
m := martini.Classic()
var str string
m.Get("/hello/:user", func(params martini.Params) string {
var userId = params["user"]
err = db.QueryRow(
"select name from users where id = userId").Scan(&str)
if err != nil && err != sql.ErrNoRows {
fmt.Println(err)
}
return "Hello " + str
})
m.Run()
defer db.Close()
}
As you can see my goal is to take the input variable (user) and insert that into a variable called userId. Then I'd like to query the database against that variable to fetch the name. Once that all works I'd like to respond back with the name of the user.
Can anyone help? It would be much appreciated as I continue my journey to learn Go!
I haven't used it, but looking at the docs, is this what you are after?
db.QueryRow("SELECT name FROM users WHERE id=?", userId)
I assume it should replace the ? with userId in a sql safe way.
http://golang.org/pkg/database/sql/#DB.Query
You can try it this way.
var y string // Variable to store result from query.
err := db.QueryRow("SELECT name from user WHERE id = $1", jobID).Scan(&y)
if err != nil && err != sql.ErrNoRows {
fmt.Println(err)
}
Documentation reference: https://pkg.go.dev/database/sql#pkg-variables