Golang 切片的结构或新手在构建 REST 时遇到麻烦
Golang slices of struct or newbie trouble building REST
需要你的帮助。
想要构建简单的 api 并遇到了一些问题。
我选择 gin and database/sql with postgres driver
package main
import (
"database/sql"
"fmt"
"github.com/gin-gonic/gin"
_ "github.com/lib/pq"
)
func main() {
router := gin.Default()
router.GET("/search/:text", SearchWord)
router.Run(":8080")
}
我需要查询数据库并从这个请求中得到 json。
func checkErr(err error) {
if err != nil {
panic(err)
}
}
type Message struct {
ticket_id int `json:"ticket_id"`
event string `json:"event"`
}
func SearchWord(c *gin.Context) {
word := c.Params.ByName("text")
db, err := sql.Open("postgres", "host=8.8.8.8 user= password= dbname=sample")
defer db.Close()
checkErr(err)
rows, err2 := db.Query("SELECT ticket_id,event FROM ...., word)
checkErr(err)
for rows.Next() {
var ticket_id int
var event string
err = rows.Scan(&ticket_id, &event)
checkErr(err)
fmt.Printf("%d | %s \n\n", ticket_id, event)
}
}
这个尾声很好用,但是当我需要制作时 json。
我需要制作一行的结构
type Message struct {
ticket_id int `json:"ticket_id"`
event string `json:"event"`
}
然后我需要创建 slice ,并附加每个 rows.Next() 循环,然后用 Json...
对浏览器进行回答
c.JSON(200, messages)
但是怎么做...不知道:(
免责声明:我是全新的
由于您 Scan
将列数据放入变量中,您应该能够使用它们的值初始化结构:
m := &Message{ticket_id: ticket_id, event: event}
您可以使用
初始化切片
s := make([]*Message, 0)
然后在实例化后附加每个消息结构:
s = append(s, m)
因为我不太熟悉 go 有几件事我不确定:
在使用 rows.Scan
将数据从查询复制到您的 vars 后,初始化 Message
结构会按预期复制当前迭代值吗??
如果有一种方法可以从查询中获取总行数,那么初始化静态长度数组而不是切片可能会更高效?
我认为@inf 删除了关于将 Message
编组到 json 的答案可能需要解决,并且 Message
字段可能需要大写
从@inf 复制:
The names of the members of your struct need be capitalized so that
they get exported and can be accessed.
type Message struct {
Ticket_id int `json:"ticket_id"`
Event string `json:"event"` }
我要在这里作弊并在此过程中解决一些问题:
首先:在程序启动时打开一次数据库连接池(而不是在每次请求时)。
其次:我们将使用 sqlx 来更轻松地将我们的数据库行编组到我们的结构中。
package main
var db *sqlx.DB
func main() {
var err error
// sqlx.Connect also checks that the connection works.
// sql.Open only "establishes" a pool, but doesn't ping the DB.
db, err = sqlx.Connect("postgres", "postgres:///...")
if err != nil {
log.Fatal(err)
}
router := gin.Default()
router.GET("/search/:text", SearchWord)
router.Run(":8080")
}
// in_another_file.go
type Message struct {
TicketID int `json:"ticket_id" db:"ticket_id"`
Event string `json:"event" db:"event"`
}
func SearchWord(c *gin.Context) {
word := c.Params.ByName("text")
// We create a slice of structs to marshal our rows into
var messages []*Message{}
// Our DB connection pool is safe to use concurrently from here
err := db.Select(&messages, "SELECT ticket_id,event FROM ...., word)
if err != nil {
http.Error(c.Writer, err.Error(), 500)
return
}
// Write it out using gin-gonic's JSON writer.
c.JSON(200, messages)
}
我希望这很清楚。 sqlx
还负责为您调用 rows.Close()
,否则会挂起连接。
需要你的帮助。 想要构建简单的 api 并遇到了一些问题。 我选择 gin and database/sql with postgres driver
package main
import (
"database/sql"
"fmt"
"github.com/gin-gonic/gin"
_ "github.com/lib/pq"
)
func main() {
router := gin.Default()
router.GET("/search/:text", SearchWord)
router.Run(":8080")
}
我需要查询数据库并从这个请求中得到 json。
func checkErr(err error) {
if err != nil {
panic(err)
}
}
type Message struct {
ticket_id int `json:"ticket_id"`
event string `json:"event"`
}
func SearchWord(c *gin.Context) {
word := c.Params.ByName("text")
db, err := sql.Open("postgres", "host=8.8.8.8 user= password= dbname=sample")
defer db.Close()
checkErr(err)
rows, err2 := db.Query("SELECT ticket_id,event FROM ...., word)
checkErr(err)
for rows.Next() {
var ticket_id int
var event string
err = rows.Scan(&ticket_id, &event)
checkErr(err)
fmt.Printf("%d | %s \n\n", ticket_id, event)
}
}
这个尾声很好用,但是当我需要制作时 json。 我需要制作一行的结构
type Message struct {
ticket_id int `json:"ticket_id"`
event string `json:"event"`
}
然后我需要创建 slice ,并附加每个 rows.Next() 循环,然后用 Json...
对浏览器进行回答c.JSON(200, messages)
但是怎么做...不知道:(
免责声明:我是全新的
由于您 Scan
将列数据放入变量中,您应该能够使用它们的值初始化结构:
m := &Message{ticket_id: ticket_id, event: event}
您可以使用
初始化切片s := make([]*Message, 0)
然后在实例化后附加每个消息结构:
s = append(s, m)
因为我不太熟悉 go 有几件事我不确定:
在使用
rows.Scan
将数据从查询复制到您的 vars 后,初始化Message
结构会按预期复制当前迭代值吗??如果有一种方法可以从查询中获取总行数,那么初始化静态长度数组而不是切片可能会更高效?
我认为@inf 删除了关于将
Message
编组到 json 的答案可能需要解决,并且Message
字段可能需要大写
从@inf 复制:
The names of the members of your struct need be capitalized so that they get exported and can be accessed.
type Message struct { Ticket_id int `json:"ticket_id"` Event string `json:"event"` }
我要在这里作弊并在此过程中解决一些问题:
首先:在程序启动时打开一次数据库连接池(而不是在每次请求时)。
其次:我们将使用 sqlx 来更轻松地将我们的数据库行编组到我们的结构中。
package main
var db *sqlx.DB
func main() {
var err error
// sqlx.Connect also checks that the connection works.
// sql.Open only "establishes" a pool, but doesn't ping the DB.
db, err = sqlx.Connect("postgres", "postgres:///...")
if err != nil {
log.Fatal(err)
}
router := gin.Default()
router.GET("/search/:text", SearchWord)
router.Run(":8080")
}
// in_another_file.go
type Message struct {
TicketID int `json:"ticket_id" db:"ticket_id"`
Event string `json:"event" db:"event"`
}
func SearchWord(c *gin.Context) {
word := c.Params.ByName("text")
// We create a slice of structs to marshal our rows into
var messages []*Message{}
// Our DB connection pool is safe to use concurrently from here
err := db.Select(&messages, "SELECT ticket_id,event FROM ...., word)
if err != nil {
http.Error(c.Writer, err.Error(), 500)
return
}
// Write it out using gin-gonic's JSON writer.
c.JSON(200, messages)
}
我希望这很清楚。 sqlx
还负责为您调用 rows.Close()
,否则会挂起连接。