2013-10-14 3 views
5

Моя структура каталогов выглядит следующим образом:Как разделить URLS в нескольких файлах с помощью gorilla/mux?

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) 
} 

Теперь я хочу добавьте больше модулей и спросите себя, если (и как) можно определить URL-адреса в модуле в файле urls.go и как-то «импортировать» их в start.go. В частности, я хочу, чтобы start.go знал все URL-адреса во всех файлах somemodule/urls.go только с одним импортом или какой-то функцией module.GetURLs.

ответ

3

EDIT:

Чтобы создать группу 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) 
} 

Playground

ОРИГИНАЛЬНЫЙ ОТВЕТ:

Вам не нужно import их, если они находятся в го e same package.

Вы можете определить переменные URL в 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.

+0

что работает, и я знаю, что это возможно - но это не решает мою проблему напрямую. Даже если я получаю все URL-адреса, экспортированные в start.go, как я могу создать для них маршрут с соответствующим обработчиком? Я хочу сделать все HandleFunc() - stuff в модулеX/urls.go, а затем «использовать» эти маршрутизаторы (или маршруты или HandleFuncs?) В start.go. С помощью одного модуля я мог бы просто определить маршрутизатор в urls.go и использовать их в start.go, но с несколькими модулями мне нужен способ «добавить» к маршрутизатору. – Subito

+1

Создайте карту URL-адресов для 'http.HandlerFunc', затем создайте функцию для инициализации всех этих файлов как 'mux.Route'? – Intermernet

+0

Хорошо, теперь я сделал что-то вроде этого: 'Func GetRoutes() [] {core.Route \t маршрутов: = [] {core.Route \t \t core.Route {URL: "/ новый /", Handler: NewObjHandler }, \t \t core.Route {URL: "/", Handler: login.LoginFirst (ListObjHandler)}, \t} \t обратные маршруты } 'в моем urls.go и' obj_routes: = obj.GetRoutes() \t s:. = r.PathPrefix ("/ объект /") Subrouter() \t для _, маршрут: = диапазон obj_routes { \t \t s.HandleFunc (route.URL, route.Handler) \t} '- который работает, но выглядит уродливым. И я не знаю, как я могу применить '.Methods (« POST »)' от gorillas mux. – Subito

4

Почему бы не заставить обработчиков встать в таблицу маршрутов?

Если вы определяете каждый обработчик в своем собственном файле идут, используйте `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 
} 

Init() вызывается для каждого файла в пакете перед выполнением пакета основного(), поэтому вы можете быть уверены, что все ваши обработчики будут зарегистрированы, прежде чем пинать сервер выключен.

Эта модель может быть расширена, чтобы обеспечить более Трикси регистрации Габбинс произойти по мере необходимости, так как сами модули теперь отвечает за их собственной регистрации, вместо того, чтобы пытаться втиснуть все особые случаи в одной регистрации FUNC

+0

безупречный! Я попробую это. Если каждый модуль полностью отвечает за свои маршруты, это лучшее решение. – Subito

+0

Спасибо, что разместили это. Помог мне много! –

Смежные вопросы