如何正确地将控制器设置为 Golang 中的路由?

我是Golang的新手,需要一些帮助。我正在尝试创建没有 ORM 的 REST API Web 服务。


现在我已成功连接到PostgreSQL数据库。在数据库中,我有一个名为factors. 我想创建 CRUD 操作。问题出在控制器逻辑上。


主要去:


package main


import (

    "github.com/gorilla/mux"

    "log"

    "net/http"

    "rest_api/configurations"

    "rest_api/controllers"

)


func main()  {

    db, err := configurations.PostgreSQLDatabase()

    if err != nil {

        log.Fatal(err)

    }


    router := mux.NewRouter()


    router.StrictSlash(true)


    subrouter := router.PathPrefix("/api").Subrouter()


    subrouter.HandleFunc("/factors", controllers.GetFactors(db)).Methods("GET")


    log.Fatal(http.ListenAndServe(":8000", router))

}

模型/factors.go:


package models


type Factor struct {

    ID int `json:"id"`

    Name string `json:"name"`

}

控制器看起来有多正确GetFactors?有人可以告诉我吗?例如,我将db对象传递给GetFactors控制器,如下例所示。不幸的是,它似乎是不正确的。


控制器/factors.go:


func GetFactors(db *sql.DB, w http.ResponseWriter, req *http.Request) {

    // some code

}

配置/PostgreSQL.go :


func PostgreSQLDatabase() (*sql.DB, error) {

    // Load environment variables from ".env" file.

    err := godotenv.Load(".env")

    if err != nil {

        log.Fatal(err)

    }


    // Initialize database-related variables.

    dbUser := os.Getenv("PostgreSQL_USER")

    dbPassword := os.Getenv("PostgreSQL_PASSWORD")

    dbHost := os.Getenv("PostgreSQL_HOST")

    dbName := os.Getenv("PostgreSQL_DB_NAME")

    dbURL := fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable", dbUser, dbPassword, dbHost, dbName)


    // Create PostgreSQL database connection pool.

    db, err := sql.Open("postgres", dbURL)

    if err != nil {

        return nil, err

    }


    // Ping PostgreSQL database to make sure it's alive.

    err = db.Ping()

    if err != nil {

        log.Fatal(err)

    } else {

        log.Println("Web service successfully connected to remote PostgreSQL database.")

    }


    return db, nil

}


米脂
浏览 133回答 3
3回答

慕标5832272

我喜欢使用的一种模式是定义您自己的Router结构,该结构具有一个mux.Router字段,并封装诸如您的数据库连接、应用程序配置等内容。我发现这样做可以在需要不同资源和开发收益时轻松更新您的路线。首先创建一个路由器对象,它在创建时接收数据库连接,并使其可用于您希望使用的所有路由。路由器.gopackage mainimport (    "net/http"    "database/sql"    "github.com/gorilla/mux")type Router struct {    router *mux.Router    db *sql.DB}func NewRouter(db *sql.DB) (*Router, error) {    router := mux.NewRouter()    router.StrictSlash(true)    subrouter := router.PathPrefix("/api").Subrouter()    r := &Router{        router: router,        db: db,    }    subrouter.HandleFunc("/factors", r.GetFactors).Methods(http.MethodGet)    return r, nil}func (r *Router) GetFactors(w http.ResponseWriter, req *http.Request) {    // Now you can access your database via `r.db`}// Needed so we can pass our custom router to ListenAndServe.func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {    r.router.ServeHTTP(w, req)}然后main.go你可以简单地创建你的自定义路由器,将它传递给你的数据库连接。然后自定义路由器可以直接传递给ListenAndServe.主程序package mainimport (    "log"    "net/http"    "rest_api/configurations"    "rest_api/controllers")func main()  {    db, err := configurations.PostgreSQLDatabase()    if err != nil {        log.Fatal(err)    }    router, err := NewRouter(db)    if err != nil {        log.Fatalf("error initializing router: %v", err)    }    log.Fatal(http.ListenAndServe(":8000", router))}希望这会有所帮助。

梵蒂冈之花

没有正确的方法,它主要基于意见。HandlerFunc 函数的语义应该是这样的func(w http.ResponseWriter, r *http.Request),为了传递数据库,你可以使用闭包,这里是一个例子。主程序// ... some code here subrouter.HandleFunc("/factors", controllers.GetFactors(db)).Methods("GET")// ... some code here控制器/factors.gofunc GetFactors(db *sql.DB) http.HandlerFunc {  return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {    // some code  })}另外一个选择:我不太确定这一点,但你可以根据你的需要调整它。初始化一个Controller结构并将数据库传递给它:主程序// ... some code here db, err := configurations.PostgreSQLDatabase()if err != nil {    log.Fatal(err)}ctrl := controllers.Controller{DB: db}subrouter.HandleFunc("/factors", ctrl.GetFactors).Methods("GET")// ... some code here表示 Controller 结构上的方法。在控制器中定义一个结构控制器/factors.gotype Controller struct {  DB *PostgreSQLDatabase}func (c Controller) GetFactors(w http.ResponseWriter, req *http.Request) {    // some code    // c.DB.MySqlMethod()}

牧羊人nacy

您的功能GetFactors必须如下所示:func GetFactors(w http.ResponseWriter, r *http.Request) {}在主文件中你必须有:subrouter.HandleFunc("/factors", controllers.GetFactors).Methods("GET")为了获得数据库连接,你必须GetDB在你的包中有类似的功能"rest_api/configurations"。在"rest_api/configurations"你必须有类似的东西:var db *PostgreSQLDatabasefunc init() {    var err error    db, err = configurations.PostgreSQLDatabase()    if err != nil {        log.Fatal(err)    }}func GetDB() *PostgreSQLDatabase {  return db}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go