Сегодня в этой статье мы будем писать для нашего предыдущегоHTTP
На сервере добавлена функция комплексной маршрутизации и группового управления маршрутизацией. В предыдущей статье "Глубокое погружение в написание HTTP-серверов в Go"подробно об использованииnet/http
Реализованные методы регистрации маршрутизации, мониторинга сетевых подключений, обработки запросов и безопасного отключения сервисов очень удобны в использовании. ноnet/http
Одна вещь, которую он делает не очень хорошо, это то, что он не предоставляет что-то вродеURL
Сложные функции маршрутизации, такие как анализ фрагментов и привязка параметров маршрутизации. хорошая вещьGo
В сообществе очень популяренgorilla/mux
пакет, обеспечивающий поддержку сложных функций маршрутизации. В сегодняшней статье мы рассмотрим, как использоватьgorilla/mux
пакет для создания именованных параметров,GET/POST
Маршруты, которые обрабатывают, группируют префиксы и ограничивают доступ к доменным именам.
Установитьgorilla/mux
Сумка
мы писали раньшеHTTP
Корень кода службы, установите пакет с GitHub с помощью команды go get следующим образом:
go get github.com/gorilla/mux
существует"Глубокое погружение в написание HTTP-серверов в Go«Мы представили, что вызовы функций регистрации маршрута, сопоставления и окончательной обработки выполняютсяServeMux
(сервисный мультиплексор) для завершения, и мы также определяем наш собственный мультиплексор для замены стандартногоDefaultServeMux
. такой жеgorilla/mux
Пакет также предоставляет нам мультиплексор. Этот мультиплексор имеет множество функций для улучшения записиWeb
эффективность применения, но и со стандартомhttp.ServeMux
совместимый.
использоватьgorilla/mux
Сумка
Создать маршрутизатор
Маршрутизатор можно создать так
router := mux.NewRouter()
вернетmux.Router
пример,mux.Router
Сопоставьте входящие запросы со списком зарегистрированных маршрутов и сопоставьтеURL
или другие условия, соответствующие обработчику вызова маршрута. Основные особенности:
- Может основываться на хосте URL, пути, префиксе пути,
Header
заголовок, значение запроса,HTTP
метод для сопоставления маршрутов или используйте пользовательский сопоставитель. - Хост URL, путь и значения запроса могут быть переменными с необязательными регулярными выражениями.
- Маршруты можно использовать в качестве дочерних маршрутов, и они будут пытаться сопоставить дочерние маршруты только в том случае, если совпадает родительский маршрут. Это полезно для определения групп маршрутизации, которые могут совместно использовать хосты, префиксы пути или другие общие атрибуты.
- Он реализует интерфейс http.Handler и поэтому совместим со стандартным
http.ServeMux
Полностью совместим.
Зарегистрировать обработчик маршрута
Заменяем кастомный сервисный мультиплексор в предыдущей программе на созданный вышеmux.Router
и зарегистрируйте для него обработчик маршрута.
type helloHandler struct{}
func (*helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome!")
}
func main() {
router := mux.NewRouter()
router.Handle("/", &helloHandler{})
router.HandleFunc("/welcome", WelcomeHandler)
......
}
Ранее мы использовалиhttp.Hanle
,http.HandleFunc
Зарегистрируйте обработчик, здесь он напрямую заменяется наrouter.Hanle
а такжеrouter.HanleFunc
Вот именно, это очень удобно.
Определение маршрута с именованными параметрами
использоватьmux.Router
Самым большим преимуществом является то, что вы можете запроситьURL
Фрагменты извлекаются из , и передаются в обработчик маршрута как именованные параметры для использования.
Далее регистрируем обработчик маршрута для нашей программы, чтобы сервер мог его обработатьURL
за/names/Gorge/countries/NewZealand
запрос:
router.HandleFunc("/names/{name}/countries/{country}", func(writer http.ResponseWriter, request *http.Request) {
......
})
Далее в функции обработчика используйтеmux.Vars()
функции от этихURL
Получить данные по сегментам. Функция начинается сhttp.Request
в качестве параметра и вернутьURL
Сегменты являются именованными ключами, а извлеченные данные представляют собой словарь значений.
func(writer http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
name := vars["name"]
country := vars["country"]
fmt.Fprintf(writer, "This guy named %s, was coming from %s .", name, country)
})
Пусть сервер использует созданный нами роутер
Эта настройка проста, если не настроенаhttp.Server
объект, используяhttp.ListenAndServe(":8000", router)
, при использовании самоопределяемого объекта `http.Server:
server := &http.Server{
Addr: ":8080",
Handler: router,
}
Это и мы передаем мультиплексор пользовательского сервиса вhttp.Server
Нет никакой разницы.
После преобразования, которое мы написали ранееHTTP
Затем сервер может динамически формировать ответ на основе определенного URL-адреса. ключевое слово ответhttp02
Доступен полный исходный код
разноеgorilla/mux
Общие функции маршрутизаторов
Установите HTTP-метод маршрута
Ограничить обработчик маршрутов только обработкой указанногоHTTP
запрос метода:
router.HandleFunc("/books/{title}", CreateBook).Methods("POST")
router.HandleFunc("/books/{title}", ReadBook).Methods("GET")
router.HandleFunc("/books/{title}", UpdateBook).Methods("PUT")
router.HandleFunc("/books/{title}", DeleteBook).Methods("DELETE")
Выше приведена группа, которая может реагировать на конкретныеHTTP
методRESTful
стиль маршрутизации интерфейса.
Установить доменное имя маршрута
Ограничьте обработчик маршрута только обработкой запросов на доступ к указанному доменному имени и маршруту:
router.HandleFunc("/books/{title}", BookHandler).Host("www.mybookstore.com")
Ограничить схемы HTTP
Сделать обработчик запроса отзывчивымHTTP
Программа ограниченаhttp
илиhttps
.
router.HandleFunc("/secure", SecureHandler).Schemes("https")
router.HandleFunc("/insecure", InsecureHandler).Schemes("http")
Установить префиксы пути и подмаршруты
bookrouter := router.PathPrefix("/books").Subrouter()
bookrouter.HandleFunc("/", AllBooks)
bookrouter.HandleFunc("/{title}", GetBook)
использоватьgorilla/mux
улучшить нашHTTP
сервер
Далее мы используемgorilla/mux
к тому, что мы писали ранееHTTP
Сделать некоторые улучшения на сервере, прежде чем все наши программы были размещеныmain.go
, сейчас наша программа еще очень маленькая, так что не будем сильно усложнять директорию проекта, сначала сделаем простое разделение обязанностей через файлы, и создадим два новых файлаrouter.go
а такжеhandler.go
Они соответственно используются для хранения логики регистрации маршрута и функции процессора, соответствующей маршруту.Пример содержимого двух файлов следующий.
handler.go
:
package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
)
type HelloHandler struct{}
func (*HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
func ShowVisitorInfo(writer http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
name := vars["name"]
country := vars["country"]
fmt.Fprintf(writer, "This guy named %s, was coming from %s .", name, country)
}
router.go
:
package main
import (
"github.com/gorilla/mux"
)
func RegisterRoutes(r *mux.Router) {
indexRouter := r.PathPrefix("/index").Subrouter()
indexRouter.Handle("/", &HelloHandler{})
userRouter := r.PathPrefix("/user").Subrouter()
userRouter.HandleFunc("/names/{name}/countries/{country}", ShowVisitorInfo)
}
существуетrouter.go
В мы делим маршруты наindex
а такжеuser
Две группы соответственно определяют маршруты в двух группах маршрутизации. Инкапсулируйте эту часть в экспортируемую функциюRegisterRoutes
для вызова. Таким образом, даже если программу, зарегистрированную маршрутом, в будущем нужно поместить в отдельный каталог, ее можно будет вызывать извне.
После окончания нашегоmain.go
станет очень лаконичным:
func main() {
//mux := http.NewServeMux()
//mux.Handle("/", &helloHandler{})
muxRouter := mux.NewRouter()
RegisterRoutes(muxRouter)
server := &http.Server{
Addr: ":8080",
Handler: muxRouter,
}
......
err := server.ListenAndServe()
......
}
Обратите внимание на ответ на общедоступный номерgo-http-02
Получите полный пример кода в этой статье.
Предыдущий обзор:Глубокое погружение в написание HTTP-серверов в Go
Если вам понравилась моя статья, пожалуйста, помогите переслать ее и поставьте лайк Если у вас возникнут какие-либо проблемы в процессе практики, вы можете оставить мне сообщение ниже.