вторник, 23 июля 2019 г.

Пакет Gorilla mux: маршруты, субмаршруты

Маршруты также могут быть ограничены доменом или поддоменом. Просто определите шаблон хоста для сопоставления. Они также могут иметь переменные:

r := mux.NewRouter()
// Соответствует только если домен "www.example.com".
r.Host("www.example.com")
// Соответствует динамическому поддомену.
r.Host("{subdomain:[a-z]+}.domain.com")

Есть несколько других совпадений, которые можно добавить. Чтобы соответствовать префиксам пути:

r.PathPrefix("/products/")

... или методам HTTP:

r.Methods("GET", "POST")

... или схеме URL:

r.Schemes("https")

... или значению заголовка:

r.Headers("X-Requested-With", "XMLHttpRequest")

... или значению запроса:

r.Queries("key", "value")

... или использовать пользовательскую функцию соответствия:

r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
    return r.ProtoMajor == 0
})

... и, наконец, можно объединить несколько сопоставителей в одном маршруте:

r.HandleFunc("/products", ProductsHandler).
  Host("www.example.com").
  Methods("GET").
  Schemes("http")

Задавать одни и те же условия сопоставления снова и снова может быть скучно, поэтому есть способ сгруппировать несколько маршрутов с одинаковыми требованиями. Он называется "субмаршрутизацией" (subrouting).

Например, допустим, есть несколько URL-адресов, которые должны совпадать только в том случае, если хостом является "www.example.com". Создайте маршрут для этого хоста и получите от него "субмаршрутизатор" ("subrouter"):

r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()

Затем зарегистрируйте маршруты в субмаршрутизаторе(subrouter):

s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)

Три URL-пути, которые мы зарегистрировали выше, будут проверяться только в том случае, если домен является "www.example.com", поскольку сначала проверяется подчиненный маршрутизатор (subrouter). Это не только удобно, но и оптимизирует сопоставление запросов. Вы можете создавать субмаршрутизаторы (subrouters), комбинирующие любые сопоставления атрибутов, принятые маршрутом (route).

Субмаршрутизаторы (Subrouters) могут использоваться для создания "пространств имен" ("namespaces") домена или пути: вы определяете субмаршрутизаторы в одном месте, а затем части приложения могут регистрировать свои пути относительно данного субмаршрутизатора.

Есть еще одна вещь о субмаршрутах (subroutes). Когда у подчиненного маршрутизатора (subrouter) есть префикс пути, внутренние маршруты используют его в качестве основы для своих путей:

r := mux.NewRouter()
s := r.PathPrefix("/products").Subrouter()

// "/products/"
s.HandleFunc("/", ProductsHandler)

// "/products/{key}/"
s.HandleFunc("/{key}/", ProductHandler)

// "/products/{key}/details"
s.HandleFunc("/{key}/details", ProductDetailsHandler)

Обратите внимание, что путь к PathPrefix() представляет собой "подстановочный знак" ("wildcard"): вызов PathPrefix("/static/").Handler(...) означает, что обработчику будет передан любой запрос, соответствующий "/static/*". Это позволяет легко обслуживать статические файлы с помощью mux:

func main() {
    var dir string

    flag.StringVar(&dir, "dir", ".", "каталог для обслуживания файлов. По умолчанию текущий каталог")
    flag.Parse()
    r := mux.NewRouter()

    // Это будет обслуживать файлы по адресу 
    // http://localhost:8000/static/
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

    srv := &http.Server{
        Handler:      r,
        Addr:         "127.0.0.1:8000",
        // Хорошая практика: 
        // применять таймауты для серверов, 
        // которые вы создаете!
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
    }

    log.Fatal(srv.ListenAndServe())
}


Читайте также:


Комментариев нет:

Отправить комментарий