将对Redis实例的引用传递给Gorilla / Mux Handler [英] Pass a reference to a Redis instance to a Gorilla/Mux Handler
问题描述
我正在玩弄一些
其中 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,//默认
})
pong,err:= client.Ping()。Result()
if(err!= nil){
fmt.Println(无法初始化Redis客户端,错误)
}
fmt.Println(Redis客户端已成功初始化。 。 ,pong)
return * client
}
其中 main.go 调用 redismanager.InitRedisClient
并初始化 mux.Handlers
:
包主
导入(
github.com/gorilla/mux
github.com/go-redis/redis
net / http
fmt
log
encoding / json
io / ioutil
../redismanager
../api
)
类型RedisInstance结构{
RInstance * redis.Client
func main(){
//初始化Redis客户端
客户端:= redismanager.InitRedisClient()
//获取当前redis实例以传递给不同的Gorilla-Mux处理程序
redisHandler:=& RedisInstance {RInstance:& client}
//初始化路由器处理程序
r:= mux.NewRouter( )
r.HandleFunc(/ todo,redisHandler.AddTodoHandler)。
方法(POST)
fmt.Println(侦听端口:8000。 。 。)
//绑定到一个端口并在
log.Fatal中传递我们的路由器(致命(http.ListenAndServe(:8000,r))
}
现在,我可以轻松定义并正常工作 AddTodoHandler $ (c * RedisInstance)AddTodoHandler(w http.ResponseWriter,r * http)在这个文件中,c $ c> .Request){
... doSomething
}
但是,事情有点模块化,我试图将所有这些 RouteHandlers
移动到 api
包中的相应文件中。为了做到这一点,我需要传递一个对 redisHandler
的引用,但是我试图用 api中的Handler来做这件事时遇到一些困难
例如,如果在主体中添加:
<$ p $
方法(GET)
$ c $($ / code> r.HandleFunc(/ todo / {id},api.GetTodoHandler(& client) C>
与 gettodo.go
package api
导入(
净/ http
github.com/gorilla/mux
fmt
编码/ 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仍然很陌生,即使经过多次研究和阅读,仍未找到任何更清晰的解决方案。
我的方法是正确的还是有更好的方法? 解决方案
编写一个函数, RedisHandler(c * RedisInstance,
f func(c * RedisInstance,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))方法(POST)
其中客户端
是Redis实例。
I'm trying to get my hands dirty while playing with some Gorilla/Mux and Go-Redis but I'm facing a little implementation problem here.
Essentially I have a project structured like the following:
Where redismanager.go handles the initialization of a Redis Client:
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
}
Where main.go calls redismanager.InitRedisClient
and initializes 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))
}
Now, I can easily define and let work properly AddTodoHandler
in the same file like:
func (c *RedisInstance) AddTodoHandler(w http.ResponseWriter, r *http.Request) {
. . . doSomething
}
But, to make things a bit more modular, I'm trying to move all of these RouteHandlers
inside their respective files in api
package. In order to make that, I need to pass a reference to redisHandler
but I'm having some difficulties when trying to make that with an Handler inside api
package.
For instance, If in the main I add:
r.HandleFunc("/todo/{id}", api.GetTodoHandler(&client)).
Methods("GET")
with 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
}
}
It works nicely.
I'm still pretty new to Go and haven't found any cleaner solution to that even after several researches and reads.
Is my approach correct or are there any better ones?
Write a function that converts a function with the Redis instance argument to an HTTP handler:
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) })
}
Write your API handlers like this:
func AddTodoHandler(c *RedisInstance, w http.ResponseWriter, r *http.Request) {
...
}
Add to the mux like this:
r.Handler("/todo", redisHandler(client, api.AddTodoHandler)).Methods("POST")
where client
is the Redis instance.
这篇关于将对Redis实例的引用传递给Gorilla / Mux Handler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!