Введение в 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. Там вы найдете заметки, дополнения, анонсы статей и многое другое.

Комментарии (2)


  1. strelkove
    15.11.2025 13:38

    Очередной нейрокал


    1. zeroqxq Автор
      15.11.2025 13:38

      Данную статью я писал сам, без использовании ИИ (Источник: chatgpt)