【问题标题】:How to add call Handlefunc outside main in Golang (Http)如何在Golang(Http)的main之外添加调用Handlefunc
【发布时间】:2022-01-30 10:02:51
【问题描述】:

我目前构建了一个有效的 golang 脚本,但为了保持连续性,如果我想添加另一个页面,我需要能够从单独的函数中调用 http.HandleFunc

我知道这不是一个好习惯,但我是 Golang 的新手。

我希望能够从单独的函数中调用主函数的 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) 部分,

下面是代码:

package main

import (
    "database/sql"
    "fmt"
    "html/template"
    "net/http"
    "strconv"

    "github.com/rs/xid"

    _ "github.com/go-sql-driver/mysql"
)

func main() {

    tmpl := template.Must(template.ParseFiles("Add-Vehicle.html"))

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if r.Method != http.MethodPost {
            tmpl.Execute(w, nil)
            return
        }

        db, err := sql.Open("mysql", "root:WgFl3f8218!@tcp(127.0.0.1:3306)/my_db")

        if err != nil {
            fmt.Println("Connection Failed.")
            panic(err.Error())
        }

        defer db.Close()

        id := xid.New()
        var brand_ = r.FormValue("select")
        var model_ = r.FormValue("select-1")

        year_, err := strconv.ParseInt(r.FormValue("year")[0:], 10, 64)
        if err != nil {
            fmt.Println(err)
        }

        mileage_, err := strconv.ParseInt(r.FormValue("text")[0:], 10, 64)
        if err != nil {
            fmt.Println(err)
        }

        dayrate_, err := strconv.ParseInt(r.FormValue("dayrate")[0:], 10, 64)
        if err != nil {
            fmt.Println(err)
        }

        insert, err := db.Query("INSERT INTO vehicle(id, date, brand, model, mileage, manufactured, rented, dayrate) VALUES ( ?, NOW(), ?, ?, ?, ?, 0, ?)", id.String(), brand_, model_, mileage_, year_, dayrate_)
        if err != nil {
            panic(err.Error())
        } 
        defer insert.Close()

        tmpl.Execute(w, struct {
            Success bool
            Brand   string
            Model   string
            Year    int64
            Mileage int64
            Dayrate int64
        }{true, brand_, model_, year_, mileage_, dayrate_})
    })

    http.Handle("/css/", http.StripPrefix("/css", http.FileServer(http.Dir("./css"))))
    http.Handle("/js/", http.StripPrefix("/js", http.FileServer(http.Dir("./js"))))
    http.Handle("/images/", http.StripPrefix("/images", http.FileServer(http.Dir("./images"))))
    http.ListenAndServe(":9090", nil)
}

每当我尝试过其他示例时,我似乎都对模板方面的事情感到困惑。

【问题讨论】:

  • 是什么阻止您将代码放在单独的函数中?

标签: go


【解决方案1】:

你正在使用 http.HandleFunc

http.HandleFunc("/", someFunction)

正如@JimB 评论的那样,为什么不把它作为一个函数提取出来呢?

func someFunction(w http.ResponseWriter, r *http.Request) {
...
}

func main() {
    http.HandleFunc("/", someFunction)
...
}

不过,在阅读您的函数时,您还要进行大量的数据库调用和模板执行,所以我认为您会遇到在函数中没有可用的情况。在这种情况下,您可能希望创建一个结构,其上具有与 HandleFunc 签名匹配或返回 HandleFunc 的方法。

看到这个SO Answer

Mat Ryer 在How I write Http Services after Eight Years 中也概述了这种技术(“处理程序挂起服务器”)。

【讨论】:

    【解决方案2】:

    您可以尝试使用光纤库来解决此问题。在 Fiber 中,您可以使用应用变量 app := fiber.New() 创建端点。如果您使用指针将此 app 变量传递给其他函数,并根据需要在该函数内创建一个端点。最后开始在 main 函数上服务这个应用程序。

    Fiber's GitHub repository

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-05
      • 2013-12-22
      • 1970-01-01
      相关资源
      最近更新 更多