> Можно ли указать кастомный заголовок в HTTP запросе (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Wildberries
Стек: Go
> Пример ответа
Короткий ответ
Да, в Go можно указать кастомный заголовок в HTTP-запросе. Для этого используется структура http.Header - map типа map[string][]string, где ключ - имя заголовка, значение - срез строк. Заголовки задаются через метод Header.Set() или Header.Add() перед отправкой запроса. Важно помнить, что некоторые заголовки (например, Host) управляются отдельно через поля структуры http.Request.
Подробное объяснение
В Go работа с HTTP-заголовками строится вокруг типа http.Header. Это обычная map, но с методами-хелперами: Set, Add, Get, Del. При создании запроса через http.NewRequest заголовки уже инициализированы, но пусты - можно сразу добавлять свои.
Ключевые моменты:
Header.Set(key, value)- заменяет все значения заголовка одним. Имя заголовка нормализуется (например,content-typeстанетContent-Type).Header.Add(key, value)- добавляет значение к существующим. Это важно для заголовков, которые могут повторяться (например,CookieилиX-Forwarded-For).- Значение заголовка - всегда строка. Числа и другие типы нужно конвертировать через
strconv. - Для кастомных заголовков принято использовать префикс
X-, хотя это не обязательное требование - просто соглашение. - Некоторые заголовки управляются не через
Header, а через поля структурыhttp.Request:Host,ContentLength,TransferEncoding. Например,Hostнельзя задать черезHeader.Set("Host", ...)- нужно присвоитьreq.Host.
При отправке запроса через http.Client.Do заголовки сериализуются в wire format. Go сам обрабатывает валидацию: запрещает некоторые символы в именах и значениях, добавляет обязательные заголовки (например, Content-Length для тела).
На практике
На практике кастомные заголовки нужны для:
- аутентификации (например,
X-API-KeyилиAuthorization- но последний часто задают черезHeader.Set); - передачи trace-информации (
X-Request-ID,X-Correlation-ID); - указания версии API (
X-API-Version); - кастомных метаданных для внутренних сервисов.
Важно помнить, что при работе с http.Client заголовки не переиспользуются между запросами - каждый запрос создаётся заново. Если нужно задать одинаковые заголовки для многих запросов, можно использовать middleware или обёртку над http.RoundTripper.
Также стоит учитывать, что некоторые прокси и серверы могут игнорировать или перезаписывать определённые заголовки (например, X-Forwarded-*). Это не проблема Go, а особенность инфраструктуры.
Пример кода
GOpackage mainimport ("context""fmt""net/http""time")func main() {ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.example.com/data", nil)if err != nil {panic(err)}// Кастомные заголовкиreq.Header.Set("X-API-Key", "secret-key-123")req.Header.Set("X-Request-ID", "req-abc-123")req.Header.Add("X-Trace", "span-1")req.Header.Add("X-Trace", "span-2") // добавит второе значение// Заголовок Host задаётся отдельноreq.Host = "custom.host.example"client := &http.Client{Timeout: 10 * time.Second}resp, err := client.Do(req)if err != nil {panic(err)}defer resp.Body.Close()fmt.Println("Status:", resp.Status)}
Как отвечать на собеседовании
Начни с прямого ответа - да, можно. Затем покажи знание структуры http.Header и методов Set/Add. Обязательно упомяни разницу между ними: Set заменяет, Add добавляет. Хорошо, если вспомнишь про Host - это показывает понимание внутреннего устройства http.Request.
Дальше можно рассказать про нормализацию имён заголовков и про то, что Go сам валидирует заголовки при отправке. Если спросят про безопасность - упомяни, что нельзя подделать некоторые заголовки на уровне клиента (например, Content-Length), потому что Go пересчитывает их автоматически.
Для уровня senior стоит добавить про http.RoundTripper и middleware - как переиспользовать заголовки между запросами. Также можно упомянуть про контекст и таймауты, если это уместно в разговоре.
Что проверяет интервьюер
Интервьюер проверяет:
- базовое знание стандартной библиотеки
net/http; - понимание разницы между
SetиAdd; - знание ограничений (например,
Host); - умение работать с заголовками в реальном коде;
- для senior - понимание жизненного цикла запроса и возможность расширения через middleware.
Если кандидат сразу говорит про Header.Set и приводит пример - это хорошо. Если ещё и упоминает RoundTripper - отлично.
Типичные ошибки
- Попытка задать
HostчерезHeader.Set("Host", ...)- не сработает, нужноreq.Host. - Использование
Header.Setдля заголовков, которые должны повторяться - теряются предыдущие значения. - Забывают про контекст и таймауты - запрос может зависнуть.
- Не проверяют ошибку от
http.NewRequest- паника в production-коде. - Путают
HeaderиTrailer- trailer-заголовки отправляются после тела, это отдельная механика. - Пытаются задать заголовок с недопустимыми символами - Go вернёт ошибку при отправке, но не при создании запроса.
> Похожие задачи по Go
Зачем нужен первичный ключ?
Что такое состояние гонки и к чему оно приводит
Что такое JWT и как он работает
Как реализовать TTL кэш на Redis без использования таблиц
> Похожие задачи по backend
Зачем нужен первичный ключ?
Что такое состояние гонки и к чему оно приводит
Что такое JWT и как он работает
Какие шаблоны проектирования часто используются
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью