我在玩一些 Gorilla/Mux 时试图弄脏我的手和 Go-Redis但我在这里遇到了一些实现问题。
基本上我的项目结构如下:
redismanager.go 处理 Redis 客户端的初始化:
package redismanager
import (
"fmt"
"github.com/go-redis/redis"
)
func InitRedisClient() redis.Client {
client := redis.NewClient(&redis.Options{
Addr : "localhost:6379",
Password: "",
DB : 0, //default
})
pong, err := client.Ping().Result()
if( err != nil ){
fmt.Println("Cannot Initialize Redis Client ", err)
}
fmt.Println("Redis Client Successfully Initialized . . .", pong)
return *client
}
main.go调用redismanager.InitRedisClient
并初始化mux.Handlers
的地方:
package main
import (
"github.com/gorilla/mux"
"github.com/go-redis/redis"
"net/http"
"fmt"
"log"
"encoding/json"
"io/ioutil"
"../redismanager"
"../api"
)
type RedisInstance struct {
RInstance *redis.Client
}
func main() {
//Initialize Redis Client
client := redismanager.InitRedisClient()
//Get current redis instance to get passed to different Gorilla-Mux Handlers
redisHandler := &RedisInstance{RInstance:&client}
//Initialize Router Handlers
r := mux.NewRouter()
r.HandleFunc("/todo", redisHandler.AddTodoHandler).
Methods("POST")
fmt.Println("Listening on port :8000 . . .")
// Bind to a port and pass our router in
log.Fatal(http.ListenAndServe(":8000", r))
}
现在,我可以在同一个文件中轻松定义并让 AddTodoHandler
正常工作,例如:
func (c *RedisInstance) AddTodoHandler(w http.ResponseWriter, r *http.Request) {
. . . doSomething
}
但是,为了使事情更加模块化,我试图将所有这些 RouteHandlers
移动到 api
包中它们各自的文件中。为了做到这一点,我需要传递对 redisHandler
的引用,但在尝试使用 api
包中的 Handler 来实现时我遇到了一些困难。
例如,如果我在主体中添加:
r.HandleFunc("/todo/{id}", api.GetTodoHandler(&client)).
Methods("GET")
使用 gettodo.go
package api
import (
"net/http"
"github.com/gorilla/mux"
"fmt"
"encoding/json"
"github.com/go-redis/redis"
)
func GetTodoHandler(c *RedisInstance) func (w http.ResponseWriter, r *http.Request) {
func (w http.ResponseWriter, r *http.Request) {
. . . doSomething
}
}
效果很好。
我对 Go 还是很陌生,即使经过多次研究和阅读,也没有找到任何更干净的解决方案。
我的方法是否正确或是否有更好的方法?
最佳答案
编写一个函数,将带有 Redis 实例参数的函数转换为 HTTP 处理程序:
func redisHandler(c *RedisInstance,
f func(c *RedisInstance, w http.ResponseWriter, r *http.Request)) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { f(c, w, r) })
}
像这样编写您的 API 处理程序:
func AddTodoHandler(c *RedisInstance, w http.ResponseWriter, r *http.Request) {
...
}
像这样添加到多路复用器中:
r.Handler("/todo", redisHandler(client, api.AddTodoHandler)).Methods("POST")
其中 client
是 Redis 实例。
关于go - 将对 Redis 实例的引用传递给 Gorilla/Mux 处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43695832/