Ответ
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 имеет значение, так как они выполняются последовательно.