🧑💻 Один middleware режет ответ в десять раз — 18 июня 2026 г. в 07:00:03.141
🧑💻 Один middleware режет ответ в десять раз Большой JSON без сжатия это лишние мегабайты по сети. На быстром канале незаметно, а пользователь на мобильном интернете ждёт лишние секунды. Лечится одним middleware, который сжимает ответ перед отправкой. Как это работает GZIP хорошо жмёт текст с повторяющимися структурами, а JSON именно такой. Клиент говорит, что умеет принимать сжатое, через заголовок Accept-Encoding: gzip. Сервер сжимает тело, ставит Content-Encoding: gzip и отдаёт. Клиент распаковывает сам, его код менять не нужно. Middleware Проверяем заголовок клиента, оборачиваем ResponseWriter в gzip.Writer и пропускаем через него ответ хендлера: func gzipMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { next.ServeHTTP(w, r) return } w.Header().Set("Content-Encoding", "gzip") gz := gzip.NewWriter(w) defer gz.Close() gzr := gzipResponseWriter{Writer: gz, ResponseWriter: w} next.ServeHTTP(gzr, r) }) } type gzipResponseWriter struct { http.ResponseWriter Writer *gzip.Writer } func (g gzipResponseWriter) Write(b []byte) (int, error) { return g.Writer.Write(b) } Подключаем к нужному эндпоинту: mux.Handle("/data", gzipMiddleware(http.HandlerFunc(dataHandler))) Проверяем размер ответа: curl http://localhost:8080/data --output raw.json curl -H "Accept-Encoding: gzip" http://localhost:8080/data --output gz.json ls -lh raw.json gz.json Когда не стоит Уже сжатые форматы вроде JPEG, PNG или ZIP жать заново смысла нет, размер почти не упадёт, а CPU потратите. Совсем мелкие ответы тоже лучше не трогать, накладные расходы перевесят. GZIP в Go это одно middleware и пара заголовков. Клиент менять не надо, а текстовый ответ ужимается в разы. В продакшене удобно взять готовый gziphandler или включить сжатие на reverse proxy, но понимать, как оно устроено, полезно в любом случае.

