Сравнение реализации встроенного HTTP-сервера Golang с наиболее популярным пакетом сообщества gorilla / mux

Эта статья представляет собой краткое изложение моих экспериментов с Golang HTTP с использованием как встроенных функций, так и самого популярного пакета, разработанного сообществом, для определения эффективного способа объявления представлений HTTP и обработки HTTP-запросов.

Встроенный пакет net / http

Объявить обработчики

Пакет net/http содержит все утилиты, необходимые для приема запросов и их динамической обработки. Мы можем зарегистрировать обработчики с http.HandleFunc. Первый параметр обработчика принимает строковый путь для сопоставления, а второй параметр - это функция, выполняемая при сопоставлении этого пути.

http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Go RESTful Series")
}

Алгоритм сопоставления - это совпадение префикса, поэтому приведенное выше объявление будет направлять каждый запрос во встроенную анонимную функцию. То есть, поскольку это всего лишь /, ему будут соответствовать все маршруты.

Прочитать запрос

Каждая функция-обработчик получает *http.Request в качестве второго параметра, который представляет собой указатель на экземпляр структуры, содержащий всю информацию, относящуюся к запросу.

r.Method  // request method
r.URL     // request URL
r.Header  // request headers
r.Body    // request body

См. Здесь для полной http.Request справки по API.

Напишите ответ

Каждая функция-обработчик получает http.ResponseWriter в качестве первого параметра, который предоставляет API для записи заголовков и тела ответа. Он реализует интерфейс io.Writer, так что мы можем писать ответ, аналогичный записи в files / stdout и т. Д.

// Set header
w.Header().Set("Some-Header", "value")
// Write using standard write method in fmt package.
fmt.Fprintf(w, "Body content")
// Write body will automatically write all previous-set header fields.

Запустить сервер

Чтобы запустить приведенный выше код, нам нужно запустить сервер.

http.ListenAndServe(":80", nil)

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

Пакеты, разработанные сообществом

Пакет Go net/http уже предоставляет приличное количество API для написания HTTP-приложений. Однако есть одна вещь, с которой он не справляется, - это сложная маршрутизация запросов, такая как сегментирование URL-адреса запроса на отдельные параметры. К счастью, есть очень популярный пакет, разработанный сообществом, который выполняет эти обязанности, под названием gorilla/mux.

Импортировать

import "github.com/gorilla/mux"

Рефакторинг кода для использования gorilla / mux

Чтобы применить gorilla/mux, нам нужно внести некоторые изменения в предыдущую реализацию.

// Create a new mux router.
r := mux.NewRouter()
// Replace http.HandleFunc by router.HandleFunc.
r.HandleFunc("/", handler)
// Replace 2nd parameter by the configured mux router.
http.ListenAndServe(":80", r)

Объявить сложные маршруты

С gorilla/mux мы можем объявлять сложные маршруты с помощью переменных, ограничивать маршруты с помощью методов и т. Д.

r.HandleFunc("/users/", listUsers).Methods(http.MethodGet)
r.HandleFunc("/users/", createUser).Methods(http.MethodPost)
r.HandleFunc("/users/{userId}/", getUser).Methods(http.MethodGet)
r.HandleFunc("/users/{userId}/", updateUser).Methods(http.MethodPut)
r.HandleFunc("/users/{userId}/", deleteUser).Methods(Http.MethodDelete)

См. Здесь для полной gorilla/mux справки по API.

Получить захваченные переменные

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

func handler(w http.ResponseWriter, r *http.Request) {
     // mux.Vars(r) returns all values captured in the request URL.
     vars := mux.Vars(r)
     // vars is a dictionary whose key-value pairs are variables' name-value pairs.
     fmt.Fprintf(w, "User %s\n", vars["userId"])
}

Как видите, стандартная реализация HTTP-сервера в Go уже достаточно эффективна. Используя gorilla/mux, мы можем получить еще более простой интерфейс для работы со сложной маршрутизацией и управлением запросами.