Тип http.ServeMux

Тип http.ServeMux (мультиплексор) является встроенным маршрутизатором в пакете net/http. Он принимает входящие HTTP-запросы и направляет их к соответствующему обработчику на основе метода и пути запроса. Мультиплексор поддерживает точное совпадение пути, а также совпадение по префиксу для пути, заканчивающегося косой чертой. Основное применение http.ServeMux - организация маршрутов в веб-приложениях на Go.

Создание мультиплексора

Для создания нового маршрутизатора используется функция http.NewServeMux. Она возвращает указатель на пустой http.ServeMux, готовый к регистрации обработчиков.

gomux := http.NewServeMux()

Регистрация обработчиков

Для регистрации обработчика используется метод Handle, который принимает строку с путем и интерфейс http.Handler. Метод HandleFunc позволяет зарегистрировать функцию-обработчик с сигнатурой func(http.ResponseWriter, *http.Request).

gomux := http.NewServeMux()

// Регистрация с использованием http.Handler
mux.Handle("/", &homeHandler{})

// Регистрация с использованием функции
mux.HandleFunc("/about", aboutHandler)

func aboutHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "About page")
}

type homeHandler struct{}

func (h *homeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Home page")
}

Пример с обработкой нескольких маршрутов

Рассмотрим пример создания веб-сервера с несколькими маршрутами, обрабатывающими разные пути:

gopackage main

import (
  "fmt"
  "net/http"
)

func main() {
  mux := http.NewServeMux()

  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Главная страница")
  })

  mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Привет, мир!")
  })

  mux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
    name := r.URL.Query().Get("name")
    if name == "" {
      fmt.Fprintf(w, "Пользователь не указан")
      return
    }
    fmt.Fprintf(w, "Привет, %s!", name)
  })

  server := &http.Server{
    Addr:  ":8080",
    Handler: mux,
  }

  fmt.Println("Сервер запущен на :8080")
  server.ListenAndServe()
}

В этом примере мультиплексор обрабатывает три пути: главную страницу, страницу приветствия и страницу пользователя с параметром в строке запроса.

Маршрутизация с префиксами

Если путь заканчивается косой чертой, http.ServeMux будет сопоставлять все запросы с этим префиксом. Это удобно для статических файлов или вложенных маршрутов:

gopackage main

import (
  "fmt"
  "net/http"
)

func main() {
  mux := http.NewServeMux()

  // Префикс /static/ будет обрабатывать все запросы,
  // начинающиеся с /static/
  mux.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
    path := r.URL.Path
    fmt.Fprintf(w, "Запрошен статический файл: %s", path)
  })

  // Точное совпадение /api
  mux.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "API эндпоинт")
  })

  http.ListenAndServe(":8080", mux)
}

Запросы на /static/style.css и /static/js/app.js будут направлены в обработчик префикса /static/, в то время как запрос на /api попадет в точный обработчик.

Использование с сервером

Мультиплексор передается в поле Handler структуры http.Server или напрямую в функцию http.ListenAndServe:

gopackage main

import (
  "fmt"
  "net/http"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
  })

  // Вариант 1: Использование с http.Server
  server := &http.Server{
    Addr:  ":8080",
    Handler: mux,
  }
  server.ListenAndServe()

  // Вариант 2: Прямая передача
  // http.ListenAndServe(":8080", mux)
}

Смотрите также

  • функцию http.NewServeMux,
    которая создает новый экземпляр мультиплексора
  • метод http.ServeMux.Handle,
    который регистрирует обработчик для указанного пути
  • метод http.ServeMux.HandleFunc,
    который регистрирует функцию-обработчик для указанного пути
  • функцию http.ListenAndServe,
    которая запускает HTTP-сервер с указанным обработчиком