我正在尝试制作这个小型 golang 应用程序的原型(prototype),并希望就如何管理我的数据库和 redis 连接对象获得一些建议。

我想创建一个“服务层”,它将包含所有与产品相关的逻辑,所以可能是 ProductService。

我希望 ProductService 引用 redis 和我的数据库客户端。

这个 ProductService 大致是什么样子,如果我需要创建它的单个实例并在整个应用程序中使用它,我是否在 var 中定义它?

func main() { 
 
  db, err := gorm.Open("postgres", "host=localhost user=blankman dbname=blank_development sslmode=disable password=") 
  if err != nil { 
    log.Fatalf("Got error when connect database, the error is '%v'", err) 
  } 
  defer db.Close() 
 
  redis := redis.NewClient(&redis.Options{ 
    Addr:     "localhost:6379", 
    Password: "", 
    DB:       0, 
  }) 
 
  pong, err := redis.Ping().Result() 
  fmt.Println(pong, err) 
 
  router := mux.NewRouter() 
 
  router.HandleFunc("/products", GetProducts).Methods("GET") 
 
  log.Fatal(http.ListenAndServe(":3001", router)) 
} 

我的 GetProducts 处理程序有您的常规签名:

func GetProducts(w http.ResponseWriter, r *http.Request)  

我应该如何将 ProductsService 传递到此处理程序中?看起来请求/响应以某种方式由 MUX 自动传递给此处理程序,所以不确定它如何获得对 ProductService 的引用?

请您参考如下方法:

使用您需要的字段创建产品服务:

type ProductService struct { 
   db *gorm.DB 
   redis *redis.Client 
} 

使 GetProducts 成为 ProductService 的方法:

func (s *ProductService) GetProducts(w http.ResponseWriter, r *http.Request)  { 
  // s.db is the database, s.redis is the redis client 
} 

在 main 中初始化 ProductService。使用 method values作为处理函数:

s := &ProductService{db: db, redis: redis} 
 
router.HandleFunc("/products", s.GetProducts).Methods("GET") 

方法值的替代方法是使用闭包将函数适配为处理程序函数:

func (s *ProductService) Handler(fn func(*ProductService, http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) { 
    return func(w http.ResponseWriter, r *http.Request) { 
        fn(s, w, r) 
    } 
} 

使用

router.HandleFunc("/products", s.Handler(PostPoduct)).Methods("POST") 

注册一个这样的函数:

func PostProduct(s *ProductService, w http.ResponseWriter, r *http.Request)  { 
} 

使用第二种方法,ProductService 层可以与各个处理程序分开。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!