go - 将对 Redis 实例的引用传递给 Gorilla/Mux 处理程序

标签 go redis gorilla

我在玩一些 Gorilla/Mux 时试图弄脏我的手和 Go-Redis但我在这里遇到了一些实现问题。

基本上我的项目结构如下:

enter image description here

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
}

ma​​in.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/

相关文章:

session - 从多种错误类型中检测特定错误

go - 在gcp cloud函数中使用gorillamux

datetime - go中如何对时间对象进行 "greater than or equal"操作?

Golang Cast接口(interface)结构

mongodb - 列族存储与文档存储

python - 构建处理 redis 和 cache_method 装饰器的测试

go - 使用 golang 扩展 websocket 连接

go - 运行 dep 时出错确保 : Grouped write of manifest, 锁和 vendor :无法统计 VerifyVendor 声称存在的文件

http - 为什么 "http.Get()"方法在 go 中抛出致命异常?

json - 使用 GO 返回一个结构数组作为 Json 响应