我是 Go 新手,所以我尝试使用 Chi 构建一个简单的 CRUD API。在
GetById
处理程序中,我使用 chi.URLParam()
方法从 URL 检索数据,但此方法返回空字符串“”。检查代码:
func GetBookByIDHandler(w http.ResponseWriter, r *http.Request) {
db, err := repository.OpenConnection()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Printf("Error while opening connection: %v", err)
return
}
defer db.Close()
repo := repository.NewBookSQLRepository(db)
useCase := usecases.NewFindBookByIDUseCase(repo)
idParam := chi.URLParam(r, "id")
//idParams = ""
var input usecases.FindBookByIDInput
input.ID = idParam
output, err := useCase.FindBookByID(input)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Printf("Error while getting book by id: %v", err)
return
}
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(output)
}
我的路由器搭建如下:
r := chi.NewRouter()
r.Get("/books", handlers.GetAllBooksHandler)
r.Get("/books/{id}", handlers.GetBookByIDHandler)
r.Post("/books", handlers.CreateBookHandler)
我在以下 URL 中使用 Insomnia 进行 HTTP 请求: http://localhost:8080/books/10
我已经尝试使请求传递查询参数为
"?id=10"
但它不起作用。
我遇到了完全相同的问题,并且没有答案,但我有一个解决方法,可以以传统方式提取 id,下面是代码的工作版本:
func GetBookByIDHandler(w http.ResponseWriter, r *http.Request) {
db, err := repository.OpenConnection()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Printf("Error while opening connection: %v", err)
return
}
defer db.Close()
repo := repository.NewBookSQLRepository(db)
useCase := usecases.NewFindBookByIDUseCase(repo)
// Split the URL path and extract the book id
parts := strings.Split(r.URL.Path, "/")
if len(parts) < 2 {
logger.Error(fmt.Sprintf("GetBookByID, Book ID not found"))
WriteJSON(w, http.StatusBadRequest, models.Response[any]{
Success: false,
Message: fmt.Sprintf("Book ID not found"),
})
return
}
idParams := parts[2]
// Assuming your book id is defined as integer in your database
id, err := strconv.Atoi(idParams)
if err != nil {
logger.Error(fmt.Sprintf("GetBookByID, invalid ID: %s", id))
WriteJSON(w, http.StatusBadRequest, models.Response[any]{
Success: false,
Message: fmt.Sprintf("invalid ID: %s", id),
})
return
}
var input usecases.FindBookByIDInput
input.ID = id
output, err := useCase.FindBookByID(input)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Printf("Error while getting book by id: %v", err)
return
}
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(output)
}
}