Обработка запросов и современный роутинг в Go 1.22+
Мы переходим к этапу, когда приложение ожидает запросов извне. В прошлой теме вы научились упаковывать данные в JSON. Теперь мы создадим точку входа (endpoint), которая примет HTTP-запрос от вашего фронтенда на React и вернет эти данные.
В Go 1.22 стандартный роутер обновился: теперь он умеет то, ради чего раньше ставили сторонние библиотеки. Мы построим API, используя только возможности стандартного пакета net/http.
Анатомия HTTP-сервера
Для работы с сетью в Go используется пакет net/http. Если в Node.js для сервера обычно нужен Express, то в Go всё необходимое встроено в стандартную библиотеку.
Главный диспетчер запросов — ServeMux (мультиплексор). Он сопоставляет URL входящего запроса с нужной функцией-обработчиком. Процесс обработки запроса показан в Схеме 1.
Маршрутизация в Go 1.22+
Раньше стандартный роутер не умел различать методы (GET/POST) и не поддерживал динамические параметры вроде /users/{id}. Разработчикам приходилось писать проверки вручную или использовать внешние роутеры (например, chi или gin).
В современных версиях Go синтаксис стал лаконичным. Метод и переменные указываются прямо в строке маршрута:
mux := http.NewServeMux()
// Маршрут с методом и динамическим параметром {id}
mux.HandleFunc("GET /tasks/{id}", getTaskHandler)
// Маршрут для создания задачи
mux.HandleFunc("POST /tasks", createTaskHandler)Обработчик запросов: HandlerFunc
Любой эндпоинт обслуживается функцией с сигнатурой HandlerFunc. У нее всегда два аргумента:
- ResponseWriter — интерфейс для отправки ответа. Через него вы записываете заголовки, статус-коды и тело ответа.
- Request — структура с данными входящего запроса (URL, заголовки, body).
Рассмотрим, как извлечь ID из URL и вернуть JSON:
func getTaskHandler(w http.ResponseWriter, r *http.Request) {
// Извлекаем параметр {id} из пути
id := r.PathValue("id")
// Подготовим данные (как в прошлом уроке)
task := Task{ID: id, Title: "Изучить роутинг в Go", Done: false}
// Устанавливаем заголовок
w.Header().Set("Content-Type", "application/json")
// Кодируем структуру в JSON и отправляем в ResponseWriter
json.NewEncoder(w).Encode(task)
}Типичные ошибки
Распространенная ошибка при переходе с TypeScript — продолжать выполнение функции после отправки ошибки.
func badHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
// ОШИБКА: Код пойдет дальше и попытается записать "Успех" в закрытый ответ.
}
w.Write([]byte("Успех"))
}В Go используется паттерн «проверь и вернись»: если возникла ошибка, отправьте её через http.Error и немедленно прервите выполнение функции с помощью return.
Запуск сервера
Чтобы сервер начал принимать соединения, нужно вызвать функцию http.ListenAndServe.
Создайте файл main.go и реализуйте сервер, который:
- Слушает порт
:8080. - Имеет маршрут
GET /status, возвращающий текст "OK" и статус-код 200. - Использует ServeMux для регистрации маршрутов.
Мы научились создавать эндпоинты и обрабатывать запросы. Однако в реальных приложениях нужно логировать запросы или проверять токены авторизации сразу для всех маршрутов.
В следующей теме мы разберем, как использовать Middleware, чтобы не дублировать общий код в каждом хендлере.
Понравился урок?
Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей
Продолжить в Telegram