Что такое Middleware в Go и для чего оно используется?

Ответ

Middleware (или промежуточное ПО) в Go — это функция, которая "оборачивает" основной обработчик HTTP-запроса (http.Handler). Она позволяет выполнить код до или после отработки основного обработчика. Middleware выстраиваются в цепочку (chain), где запрос последовательно проходит через каждый слой.

Основные задачи Middleware:

  • Аутентификация и авторизация: Проверка токенов, сессий или прав доступа.
  • Логирование: Запись информации о каждом входящем запросе.
  • Сжатие: Сжатие тела ответа (например, с помощью gzip).
  • CORS: Добавление необходимых заголовков для Cross-Origin Resource Sharing.
  • Восстановление после паники (Recovery): Перехват паники в обработчике, чтобы сервер не "упал".
  • Установка контекста: Добавление значений в context.Context запроса.

Middleware — это реализация паттерна Декоратор для веб-обработчиков.

Пример с net/http:

// loggingMiddleware логирует каждый запрос
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Код, который выполняется ДО основного обработчика
        log.Printf("Request: %s %s", r.Method, r.URL.Path)

        // Передаем управление следующему обработчику в цепочке
        next.ServeHTTP(w, r)

        // Код, который выполняется ПОСЛЕ (этот код выполнится, когда основной обработчик завершит работу)
        // Например, можно логировать статус ответа, но для этого нужна обертка для http.ResponseWriter
    })
}

func mainHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, World!"))
}

func main() {
    // Создаем основной обработчик
    mainLogicHandler := http.HandlerFunc(mainHandler)

    // Оборачиваем его в middleware
    http.Handle("/", loggingMiddleware(mainLogicHandler))

    log.Println("Server is starting on :8080")
    http.ListenAndServe(":8080", nil)
}

Порядок применения middleware имеет значение, так как они выполняются последовательно.