2015-12-31 2 views
6

я использую Gorilla Mux для написания REST API и я у меня возникают проблемы организации своих маршрутов, в настоящее время все мои маршруты определены в main.go файле, как этотКак организовать маршруты мультика гориллы?

//main.go 
package main 

import (
    "NovAPI/routes" 
    "fmt" 
    "github.com/gorilla/mux" 
    "net/http" 
) 

func main() { 

    router := mux.NewRouter().StrictSlash(true) 

    router.HandleFunc("/hello", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "Hello") 
    }) 

    router.HandleFunc("/user", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "User") 
    }) 

    router.HandleFunc("/route2", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "Route2") 
    }) 

    router.HandleFunc("/route3", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "Route3") 
    }) 

    // route declarations continue like this 

    http.ListenAndServe(":1128", router) 

} 

так, что я хочу сделать, это вынуть и разделите это объявление маршрута на несколько файлов, как бы я это сделал? заранее.

ответ

5

Как насчет этого?

//main.go 
package main 

import (
    "NovAPI/routes" 
    "fmt" 
    "github.com/gorilla/mux" 
    "net/http" 
) 

func main() { 

    router := mux.NewRouter().StrictSlash(true) 

    router.HandleFunc("/hello", HelloHandler) 
    router.HandleFunc("/user", UserHandler) 
    router.HandleFunc("/route2", Route2Handler) 
    router.HandleFunc("/route3", Route3Handler) 
    // route declarations continue like this 

    http.ListenAndServe(":1128", router) 

} 

func HelloHandler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "Hello") 
} 

func UserHandler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "User") 
} 

func Route2Handler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "Route2") 
} 

func Route3Handler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "Route3") 
} 

Таким образом, вы можете разместить своих обработчиков в других файлах или даже в других пакетах.

Если вы endup с additionnal зависимостей, таких как базы данных, вы можете даже избежать необходимости в глобальной переменной с помощью конструктора трюк:

//main.go 

func main() { 
    db := sql.Open(…) 

    //... 

    router.HandleFunc("/hello", NewHelloHandler(db)) 

    //... 
} 

func NewHelloHandler(db *sql.DB) func(http.ResponseWriter, *http.Request) { 
    return func(res http.ResponseWriter, req *http.Request) { 
     // db is in the local scope, and you can even inject it to test your 
     // handler 
     fmt.Fprintln(res, "Hello") 
    } 
} 
+0

Я сделал это для простоты, но мои обработчики на самом деле определены в пакете маршрутов, поэтому мне все равно нужно отбирать маршруты из основной функции. – zola

+2

. Я не понимаю: так или иначе вы все еще собираюсь писать ваши маршруты где-то ... Если ваш «главный» слишком длинный, возможно, вы можете написать помощник «NewRouter», который инициализирует его для вас. – Elwinar

+1

Другим решением будет иметь функцию инициализации в вашем маршрутном пакете, которая принимает маршрутизатор в качестве входных данных и добавляет маршруты по своему усмотрению. Но я настоятельно советую. – Elwinar

1

Я хотел проверить другие проекты в GitHub, чтобы захватить идеи о том, как делайте что-нибудь, и для этих случаев я обычно смотрю сначала на Docker repo. Это, как они делают это:

Для маршрутов system «s, определяют все обработчики в system_routes.go, а затем инициализировать эти маршруты на функцию NewRouter в system.go.

type systemRouter struct { 
    backend Backend 
    routes []router.Route 
} 

func NewRouter(b Backend) router.Router { 
    r := &systemRouter{ 
     backend: b, 
    } 

    r.routes = []router.Route{ 
     local.NewOptionsRoute("/", optionsHandler), 
     local.NewGetRoute("/_ping", pingHandler), 
     local.NewGetRoute("/events", r.getEvents), 
     local.NewGetRoute("/info", r.getInfo), 
     local.NewGetRoute("/version", r.getVersion), 
     local.NewPostRoute("/auth", r.postAuth), 
    } 

    return r 
} 

// Routes return all the API routes dedicated to the docker system. 
func (s *systemRouter) Routes() []router.Route { 
    return s.routes 
} 

Обратите внимание, что systemRouter реализует функцию router.Router интерфейса и маршрутов возвращает [] router.Route, и их обработчики определяются как

func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error 

вместо Go содержит стандартный обработчик HTTP:

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

Итак, есть дополнительный код для преобразования обработчика API Docker в обработчик HTTP HTTP с помощью функции makeHttpHandler.

И, наконец, чтобы добавить эти маршруты к их мультиплексору, на их server.go они реализуют несколько других функций до add middleware для своих обработчиков.

Если это то, что вы думаете, это то, что вы ищете, а затем найдите время, чтобы проанализировать код Докера для их маршрутов, и если вам нужно, чтобы я больше разрабатывал или пропустил что-либо, отправьте комментарий.

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