所以我是新手,我目前正在尝试使用 chi 构建一个小的 REST-API(我喜欢它)。昨天我遇到一个问题,我不太明白。
在我的小测试项目中,我有一个main.go
文件,其中包含路由器实例化的主要功能,添加中间件并启动服务器:
func main() {
router := chi.NewRouter()
// Middleware
router.Use(middleware.RequestID)
router.Use(middleware.RealIP)
router.Use(middleware.Logger)
router.Use(middleware.Recoverer)
// Routes
router.Post("/login", users.Login)
router.Post("/register", users.Register)
router.With(users.LoginRequired).Route("/users", func(r chi.Router) {
r.Get("/{user_id}", users.GetUser)
})
// Start Server
port := ":8080"
log.Printf("Server starting at port %v\n", port)
log.Fatal(http.ListenAndServe(port, router))
}
首先问题不存在,因为我在main.go
文件中定义了所有处理函数,并且 GetUser 函数按预期工作并从我的“数据库”(具有 3 个用户的数组)返回了一个用户:
func GetUser(w http.ResponseWriter, r *http.Request) {
uID := chi.URLParam(r, "user_id") // Problem when not in main -> uID = ""
id, err := strconv.Atoi(uID)
if err != nil {
log.Printf("Error while parsing int: %v\n", err)
// TODO: return error 400
}
user := DataBase[id-1]
response, err := json.Marshal(user)
if err != nil {
log.Printf("Error while marshalling user: %v\n", err)
}
w.Write(response)
}
一旦我将此函数从main.go
文件中移出到另一个名为users
chi.URLParam 的包中,函数就会返回一个空字符串,并且再也找不到 URLParam。我读到它与上下文有关,但我无法理解如果我想使用 chi 函数,我必须将函数放在主文件中。
我错过了什么吗?
更新
根据要求,我删除了除 GetUser 函数之外的所有内容。我的 main.go 文件目前如下所示:
package main
import (
"encoding/json"
"log"
"net/http"
"strconv"
"github.com/MyUserName/MyProjectName/internals/users"
"github.com/go-chi/chi/v5"
)
func GetUser(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(chi.URLParam(r, "user_id"))
if err != nil {
log.Printf("Error while parsing int: %v\n", err)
// TODO: return error 400
}
log.Printf("ID=%v, Current Database=%v\n", id, users.DataBase)
user := users.DataBase[id-1]
response, err := json.Marshal(user)
if err != nil {
log.Printf("Error while marshalling user: %v\n", err)
}
w.Write(response)
}
func main() {
router := chi.NewRouter()
// Routes
router.Get("/users/{user_id}", GetUser)
// Start Server
port := ":8080"
log.Printf("Server starting at port %v\n", port)
log.Fatal(http.ListenAndServe(port, router))
}
我的用户包如下所示:
package users
import (
"encoding/json"
"log"
"net/http"
"strconv"
"github.com/MyUserName/MyProjectName/internals/models"
"github.com/go-chi/chi"
)
var (
DataBase = make([]models.User, 0)
)
func GetUser(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(chi.URLParam(r, "user_id"))
if err != nil {
log.Printf("Error while parsing int: %v\n", err)
// TODO: return error 400
}
log.Printf("ID=%v, Current Database=%v\n", id, DataBase)
user := DataBase[id-1]
response, err := json.Marshal(user)
if err != nil {
log.Printf("Error while marshalling user: %v\n", err)
}
w.Write(response)
}
func init() {
initUser := []models.User{
{
ID: 1,
UserName: "john",
Password: "doe",
},
{
ID: 2,
UserName: "max",
Password: "mustermann",
},
{
ID: 3,
UserName: "jane",
Password: "doe",
},
}
for _, user := range initUser {
DataBase = append(DataBase, user)
}
log.Println("Initializing Database")
}
当我使用用户包中的函数时,它不起作用并且仍然是一个空字符串,如果我使用 main.go 文件中的函数它可以工作。
更新
所以显然我很愚蠢地两次导入相同的包。在我的主文件中,我使用了“github.com/go-chi/chi/v5”,在我的用户包中,我使用了“github.com/go-chi/chi”。使用同样解决了这个问题,非常感谢