Tôi vừa mới bắt đầu dùng thử Go và tôi đang tìm cách triển khai lại máy chủ API được viết bằng nút với nó.Go and Gin: Vượt qua cấu trúc cho bối cảnh cơ sở dữ liệu?
Tôi đã gặp trở ngại với việc cố gắng sử dụng tính năng tiêm phụ thuộc để truyền xung quanh ngữ cảnh cơ sở dữ liệu như một phần mềm trung gian gin. Cho đến nay tôi đã thiết lập nó như thế này:
main.go:
package main
import (
"fmt"
"runtime"
"log"
"github.com/gin-gonic/gin"
"votesforschools.com/api/public"
"votesforschools.com/api/models"
)
type DB struct {
models.DataStore
}
func main() {
ConfigRuntime()
ConfigServer()
}
func Database(connectionString string) gin.HandlerFunc {
dbInstance, err := models.NewDB(connectionString)
if err != nil {
log.Panic(err)
}
db := &DB{dbInstance}
return func(c *gin.Context) {
c.Set("DB", db)
c.Next()
}
}
func ConfigRuntime() {
nuCPU := runtime.NumCPU()
runtime.GOMAXPROCS(nuCPU)
fmt.Printf("Running with %d CPUs\n", nuCPU)
}
func ConfigServer() {
gin.SetMode(gin.ReleaseMode)
router := gin.New()
router.Use(Database("<connectionstring>"))
router.GET("/public/current-vote-pack", public.GetCurrentVotePack)
router.Run(":1000")
}
mô hình/db.go
package models
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
type DataStore interface {
GetVotePack(id string) (*VotePack, error)
}
type DB struct {
*sql.DB
}
func NewDB(dataSource string) (*DB, error) {
db, err := sql.Open("mysql", dataSource)
if err != nil {
return nil, err
}
if err = db.Ping(); err != nil {
return nil, err
}
return &DB{db}, nil
}
mô hình/votepack.go
package models
import (
"time"
"database/sql"
)
type VotePack struct {
id string
question string
description string
startDate time.Time
endDate time.Time
thankYou string
curriculum []string
}
func (db *DB) GetVotePack(id string) (*VotePack, error) {
var votePack *VotePack
err := db.QueryRow(
"SELECT id, question, description, start_date AS startDate, end_date AS endDate, thank_you AS thankYou, curriculum WHERE id = ?", id).Scan(
&votePack.id, &votePack.question, &votePack.description, &votePack.startDate, &votePack.endDate, &votePack.thankYou, &votePack.curriculum)
switch {
case err == sql.ErrNoRows:
return nil, err
case err != nil:
return nil, err
default:
return votePack, nil
}
}
Vì vậy, với tất cả những điều trên, tôi muốn truyền các mô hình.DataSource xung quanh như một phần mềm trung gian để nó có thể được truy cập như thế này:
công cộng/public.go
package public
import (
"github.com/gin-gonic/gin"
)
func GetCurrentVotePack(context *gin.Context) {
db := context.Keys["DB"]
votePack, err := db.GetVotePack("c5039ecd-e774-4c19-a2b9-600c2134784d")
if err != nil{
context.String(404, "Votepack Not Found")
}
context.JSON(200, votePack)
}
Tuy nhiên tôi nhận được public\public.go:10: db.GetVotePack undefined (type interface {} is interface with no methods)
Khi tôi kiểm tra trong trình gỡ lỗi (sử dụng Webstorm với plugin) db chỉ là một đối tượng có sản phẩm nào. Tôi đang cố gắng làm tốt và tránh sử dụng biến toàn cầu
Hoàn hảo, dường như giải quyết nó. –
Trong khi điều này giải quyết vấn đề, nó trông giống như thiết kế rất xấu với tôi. Dựa vào một người nào đó đặt giao diện {} trong bối cảnh chung không giống như thiết kế được đánh máy đúng đắn. Tôi đoán hầu hết các lỗi là vì gin hy vọng một chức năng cho phương pháp xử lý thay vì một giao diện –
@SnoProblem Đó là cách tốt để vượt qua kết nối cơ sở dữ liệu thông qua bối cảnh? Còn cách nào khác không&? –