我的目录结构如下所示:
myapp/
|
+-- moduleX
| |
| +-- views.go
|
+-- start.go
应用程序以start.go
开始,然后从那里我配置所有路由并从moduleX/views.go
导入处理程序,如下所示:
package main
import (
"net/http"
"github.com/gorilla/mux"
"myapp/moduleX"
)
func main() {
r := mux.NewRouter()
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
r.HandleFunc("/", moduleX.SomePostHandler).Methods("POST")
r.HandleFunc("/", moduleX.SomeHandler)
http.Handle("/", r)
http.ListenAndServe(":8080", nil)
}
现在我想添加更多模块,并问自己是否(以及如何)在urls.go
文件中定义模块中的URL并以某种方式在start.go
中“导入”它们。具体来说,我希望start.go
知道所有somemodule/urls.go
文件中的所有网址,只需一次导入或某种module.GetURLs
功能。
答案 0 :(得分:4)
为什么不让处理程序将自己插入到路由表中?
如果您在自己的go文件中定义每个处理程序,请对每个文件使用`init()`func将处理程序添加到全局路由表
类似于:
main.go:
type route{
method string
path string
handler func(w http.ResponseWriter, r *http.Request)
}
var routes = make([]route,0)
func registerRoute(r route){
routes = append(routes,r)
}
func server(){
r := mux.NewRouter()
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
// set up all the registered routes
for _, rt = range(routes){
r.HandleFunc(rt.path,rt.handler).Methods(rt.Method)
}
// and there's usually some other stuff that needs to go in here
//before we finally serve the content here!
http.ListenAndServe(":8080", nil)
}
yourmodule.go:
func init(){
r = route{
method="GET",
path="/yourmodule/path/whatever",
handler=yourHandlerFunc,
}
registerRoute(r)
}
func yourHandlerFunc(w http.ResponseWriter, r *http.Request){
//awesome web stuff goes here
}
在执行包main()之前,会为包中的每个文件调用init(),这样您就可以确保在关闭服务器之前注册所有处理程序。
这个模式可以扩展到允许更多特技注册gubbins根据需要发生,因为模块本身现在负责自己的注册,而不是试图将所有特殊情况塞进一个注册函数
答案 1 :(得分:3)
编辑:
要一次性创建一组mux.Route
,您可以在下面的示例中定义自定义类型(handler
)并执行以下操作:
package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
)
type handler struct {
path string
f http.HandlerFunc
methods []string
}
func makeHandlers(hs []handler, r *mux.Router) {
for _, h := range hs {
if len(h.methods) == 0 {
r.HandleFunc(h.path, h.f)
} else {
r.HandleFunc(h.path, h.f).Methods(h.methods...)
}
}
}
// create some example handler functions
func somePostHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "POST Handler")
}
func someHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Normal Handler")
}
func main() {
//define some handlers
handlers := []handler{{path: "/", f: somePostHandler, methods: []string{"POST"}}, {path: "/", f: someHandler}}
r := mux.NewRouter()
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
// Initialise the handlers
makeHandlers(handlers, r)
http.Handle("/", r)
http.ListenAndServe(":8080", nil)
}
原始回答:
如果他们在same package中,则您无需import
。
您可以在urls.go
中定义网址变量,然后在views.go
(或package moduleX
中的其他文件)中定义逻辑,只要它们具有相同的package
声明即可
例如:
// moduleX/urls.go
package moduleX
var (
urls = []string{"http://google.com/", "http://stackoverflow.com/"}
)
然后:
// moduleX/views.go (or some other file in package moduleX)
package moduleX
func GetUrls() []string {
return urls
}
然后:
// start.go
package main
import (
"fmt"
"myapp/moduleX"
)
func main() {
for _, url := range moduleX.GetUrls() {
fmt.Println(url)
}
}
或者,更简单一点,只需从moduleX
包中导出变量,为其提供大写名称。
例如:
// moduleX/urls.go
package moduleX
var URLs = []string{"http://google.com/", "http://stackoverflow.com/"}
然后:
// start.go
package main
import (
"fmt"
"myapp/moduleX"
)
func main() {
for _, url := range moduleX.URLs {
fmt.Println(url)
}
}
看看any of the Go source to see how they handle the same problem。一个很好的例子是the SHA512
source,其中冗长的变量存储在sha512block.go
中,逻辑位于sha512.go
。