Введение в GO
Go (Golang, go.dev) — это статически типизированный компилируемый язык программирования, разработанный компанией Google в 2009 году. Он ориентирован на простоту, производительность и эффективную поддержку конкурентности с помощью горутин и каналов. Go компилируется в нативный машинный код, что обеспечивает высокую скорость выполнения, и включает встроенный сборщик мусора для управления памятью.
Преимущества Go для создания веб-серверов
Go обладает рядом характеристик, делающих его идеальным для разработки микросервисов и веб‑серверов:
Высокая производительность: Благодаря компиляции в машинный код и эффективному рантайму, Go обрабатывает тысячи одновременных соединений с минимальными накладными расходами.
Встроенная поддержка конкурентности: Горутины позволяют легко реализовывать асинхронную обработку запросов без сложных callback‑ов или потоков.
Стандартная библиотека net/http: Возможность работы с http доступны «из коробки», без внешних зависимостей.
Простота и читаемость кода: Минималистичный синтаксис снижает порог входа и упрощает поддержку проектов.
Кросс‑платформенность и статическая линковка: Бинарные файлы легко развертываются на разных ОС без дополнительных runtime. (Но имеет рантайм в бинарнике!)
Эти качества делают Go популярным для микросервисов, API и высоконагруженных систем.
Простой веб-сервер на net/http
Стандартный пакет net/http позволяет создать базовый сервер за несколько строк кода. Ниже приведен минимальный пример HTTP-сервера, который отвечает на запросы к корневому пути и к /hello.
package main
import (
"fmt"
"net/http"
"log"
)
func main_page(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet { // Проверяем метод, если не GET - шлем ошибку
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
fmt.Fprintf(w, "Добро пожаловать на главную страницу")
}
func hello_page(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet { // Проверяем метод, если не GET - шлем ошибку
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
name := r.URL.Query().Get("name")
if name == "" {
name = "Гость"
}
fmt.Fprintf(w, "Привет, %s!", name)
}
func main() {
http.HandleFunc("/", main_page)
http.HandleFunc("/hello", hello_page)
fmt.Println("Сервер запущен на :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Пояснения к коду:
http.HandleFuncрегистрирует обработчики для конкретных путей.Функции принимают
http.ResponseWriterдля формирования ответа и*http.Requestдля доступа к данным запроса.http.ListenAndServeзапускает сервер на указанном порту.
Для тестирования: запустите go run main.go и обратитесь к http://localhost:8080/ или http://localhost:8080/hello?name=Пользователь. На странице /hello имя берётся из query-параметра name. Если не указано — используется "Гость".
⚠️ Внимание: В продакшене обрабатывайте ошибку от
ListenAndServe, как показано на примере.
Этот пример демонстрирует базовую функциональность, но для реальных проектов требуется обработка ошибок, middleware и маршрутизация.
Фреймворки для упрощения разработки
net/http — отличная база, но в реальных проектах нужен:
маршруты с параметрами (
/user/:id)middleware
JSON binding
валидация
группировка
Популярные варианты:
Gin: Легковесный, высокопроизводительный фреймворк с удобным API для маршрутов и middleware. Базирован на net/http.
Echo: Быстрый, с акцентом на производительность, поддержкой WebSocket и встроенной валидацией. Базирован на net/http.
Fiber: Вдохновлен Express.js, ориентирован на максимальную скорость и асинхронность. Базирован на Fasthttp.
Другие: Chi (минималистичный роутер), Fasthttp (самый быстрый по бенчмаркам, Gorilla (набор утилит, включая mux).
Замечание: Fasthttp — не фреймворк, а замена net/http.
Для демонстрации выберем Echo — он сочетает простоту с высокой производительностью. Установите его командой:
go get github.com/labstack/echo/v4
go get github.com/labstack/echo/v4/middleware
Давайте перепишем наш код на echo.
Пример сервера на Echo
package main
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"net/http"
)
func main_page(c echo.Context) error {
return c.String(http.StatusOK, "Добро пожаловать на главную страницу!")
}
func hello_page(c echo.Context) error {
name := c.QueryParam("name")
if name == "" {
name = "Гость"
}
return c.String(http.StatusOK, "Привет, "+name+"!")
}
func main() {
e := echo.New()
e.Use(middleware.Recover())
e.GET("/", main_page)
e.GET("/hello", hello_page)
e.Start(":8080")
}
Пояснения к коду:
echo.New()создает экземпляр сервера.Методы
GETрегистрируют обработчики;echo.Contextпредоставляет доступ к запросу/ответу.c.Stringупрощает отправку текстовых ответов.
Echo может автоматически обрабатывать паники с помощью middleware Recover(), который нужно явно включить. Также echo поддерживает группировку маршрутов и JSON-ответы.
Пример на других фреймворках
Gin
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(200, "Главная страница")
})
r.GET("/hello", func(c *gin.Context) {
name := c.Query("name")
if name == "" {
name = "Гость"
}
c.String(200, "Привет, %s!", name)
})
r.Run(":8080")
}
Chi
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Главная страница"))
})
r.Get("/hello", func(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
if name == "" { name = "Гость" }
w.Write([]byte("Привет, " + name + "!"))
})
http.ListenAndServe(":8080", r)
}
Fiber
package main
import "github.com/gofiber/fiber/v3"
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Главная страница")
})
app.Get("/hello", func(c *fiber.Ctx) error {
name := c.Query("name")
if name == "" {
name = "Гость"
}
return c.SendString("Привет, " + name + "!")
})
app.Listen(":8080")
}
Заключение
Go предоставляет мощные инструменты для создания веб-серверов: от минималистичного net/http для прототипов до производительных фреймворков вроде Echo, Gin или Fiber для полноценных приложений. Выбор зависит от требований к производительности и сложности. Начните с базового примера, а затем масштабируйте с помощью фреймворков — это позволит строить надежные, быстрые и масштабируемые сервисы. Исходный код примеров доступен на GitHub для экспериментов.
Спасибо за прочтение статьи! Я буду рад если вы подпишетесь к моему телеграм каналу по IT. Там вы найдете заметки, дополнения, анонсы статей и многое другое.
Комментарии (13)

vbelogrudov
15.11.2025 13:38Используйте современный mux, начиная с go 1.22.
http.HandleFunc("GET /", main_page), проверка на метод в хендлерах будет ненужным
apevzner
15.11.2025 13:38Используйте современный mux, начиная с go 1.22.
Вообще, за это убивать надо. А если мне надо написать программу, которая работает и на go 1.22 и на 1.21?
Лучше бы они или завели новый тип, или включали новое поведение отдельным параметром, запрещенным по умолчанию...
Я не припомню, чтобы они за всю историю Go когда-либо в такой степени ломали обратную совместимость...

zelenin
15.11.2025 13:38А если мне надо написать программу, которая работает и на go 1.22 и на 1.21?
в чем вы видите проблему?
Лучше бы они или завели новый тип, или включали новое поведение отдельным параметром, запрещенным по умолчанию...
так и было в 1.21. В 1.22 вам надо наоборот включить старый мукс вместо нового
Я не припомню, чтобы они за всю историю Go когда-либо в такой степени ломали обратную совместимость...
а она сломана?

RikkiMongoose
15.11.2025 13:38Net/http рассмотрено. А как насчёт fasthttp? В чем преимущества, в чем ограничения?
Что такое gorilla/mux? На чем он основан? Что он умеет такого, что не умеет gin?
Первую страницу в справке я тоже умею читать, но там есть и другие.

zeroqxq Автор
15.11.2025 13:38Данная статья планировалась как базовая по веб серверу на Go. Возможно рассмотрю потом эти темы

ADEXITUM
15.11.2025 13:38Не забыть ещё написать, что в echo в отличие от того же gin, контекст это не структура, а интерфейс. Для меня это стало причиной выбора именно echo, а не gin
strelkove
Очередной нейрокал
zeroqxq Автор
Данную статью я писал сам, без использовании ИИ (Источник: chatgpt)
zeroqxq Автор
Как вы определили что это ИИ?
RikkiMongoose
Рерайт справки, бесполезные сведения вроде "Fasthttp — не фреймворк, а замена net/http.". Ну замена и что? Чем он лучше, чем хуже ?
zeroqxq Автор
Там написано что он намного быстрее. Я добавил замечания чтобы не было вопросов у читателей
zeroqxq Автор
Спасибо. Приму к сведению