2016-11-11 52 views
0

在Go中編寫Web服務器時,我希望能夠在運行時取消引用符號,以使我能夠從配置文件中找出哪些函數要調用,如調用在下面的例子中虛構的「eval」函數。這將允許我從處理程序庫中選擇處理程序,並僅使用配置文件部署新的服務器。 Go有什麼方法可以完成這個任務嗎?運行時訪問Go中的符號

config.json

{ "url": "/api/apple", "handler": "Apple", "method": "get" } 
{ "url": "/api/banana", "handler": "Banana", "method": "get" } 

play.go

package main 

import (
    "github.com/gorilla/mux" 
    "net/http" 
    "encoding/json" 
    "log" 
) 

type ConfigEntry struct { 
    URL string `json:"url"` 
    Method string `json:"method"` 
    Handler string `json:"handler"` 
} 

func main() { 
    ifp, err := os.Open("config.json") 

    if err != nil { 
     log.Fatal(err) 
    } 

    dec := json.NewDecoder(ifp) 
    r := mux.NewRouter() 

    for { 
     var config ConfigEntry 

     if err = dec.Decode(&m); err == io.EOF { 
      break 
     } else if err != nil { 
      log.Fatal(err) 
     } 

     r.HandleFunc(config.URL, eval(config.Handler + "Handler")).Methods(config.Method) 
    } 

    http.Handle("/", r) 
    http.ListenAndServe(8080, nil) 
} 

func AppleHandler(w http.ResponseWriter, r *http.Request) (status int, err error) { 
    w.Write("Apples!\n") 
    return http.StatusOK, nil 
} 

func BananaHandler(w http.ResponseWriter, r *http.Request) (status int, err error) { 
    w.Write("Bananas!\n") 
    return http.StatusOK, nil 
} 
+0

我不認爲這是不可能沒有'map [string] http.Handler'。 –

+0

[在Golang中調用帶有特殊前綴或後綴的所有函數]的可能副本(http://stackoverflow.com/questions/37384473/call-all-functions-with-special-prefix-or-suffix-in-golang)。 – icza

回答

1

在Go中沒有什麼像eval,這是件好事,因爲這樣的事情非常危險。

你可以做什麼是有地圖在你的配置文件中的處理程序串映射到在你的代碼的處理功能:通過簡單地做

var handlers = map[string]func(http.ResponseWriter, *http.Request) (int, error){ 
     "Apple": AppleHandler, 
     "Banana": BananaHandler, 
} 

然後你就可以註冊這些處理程序:

handler, ok := handlers[config.Handler] 
if !ok { 
     log.Fatal(fmt.Errorf("Handler not found")) 
} 
r.HandleFunc(config.URL, handler).Methods(config.Method) 
1

有與reflect包在運行時訪問一些事情的有限的方式。但是,它不允許您在包中搜索所有合適的獨立功能。如果它們都是已知結構類型/值的方法,那將是可能的。

作爲您給出示例的替代方案,您可以簡單地使用map[string]func(...)來存儲所有處理程序,在啓動時初始化它(在init()期間)並從那裏獲取處理程序。但這或多或少地與現有的http muxes一樣。