TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7244 2.92K
🧑‍💻 Один 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, но понимать, как оно устроено, полезно в любом случае.

📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max

🐸 Библиотека Go-разработчика

#GoDeep
  • 👍 9
  • ❤ 3
  • 🌚 2
More from @goproglib
  1. Sep 29, 2026👨‍💻 Библиотека для написания LSP-серверов Написать свой Language Server с нуля на Go сло…
  2. Sep 28, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — 1 true / 0 false 🔥 — 1 true /…
  3. Sep 28, 2026👩‍💻 Что на самом деле происходит внутри Go map? После Go 1.24 обычный map внутри работае…
  4. Sep 26, 2026🔥 В Go 1.27 появился portable SIMD До этого SIMD-оптимизации в Go требовали архитектурног…
  5. Sep 25, 2026🤡🤡 📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека Go-разработчика #GoGiggle
  6. Sep 25, 2026💡 Код работает. А data race уже есть В Go можно записать значение в одной горутине, прочи…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →