Golang net/http RoundTripper: Что это и зачем

RoundTripper - это базовый механизм для выполнения HTTP-запросов.

В пакете net/http это интерфейс, содержащий единственный метод RoundTrip.

type RoundTripper interface { RoundTrip(*http.Request) (*http.Response, error) }

http.Client использует RoundTripper для обработки всех запросов. По умолчанию стандартный клиент http.DefaultClient использует реализацию RoundTripper, предоставляемую http.Transport.

RoundTripper даёт возможность внедриться в процесс между отправкой HTTP-запроса и получением ответа. Важно отметить что это происходит до фактической отправки запроса.

Несмотря на то, что в методе RoundTrip можно реализовать практически любую логику (аналогично middleware для HTTP-обработчиков), рекомендуется избегать следующих действий:

  • модификация запроса после передачи его в RoundTrip;

  • изучение содержимого ответа (это должно быть сделано на уровне вызова клиента);

  • реализация логики, связанной с аутентификацией пользователей;

  • возврата ошибки без реальной необходимости.

Чтобы воспользоваться функциональностью RoundTripper нужно просто реализовать метод RoundTrip:

type SomeClient struct {} func (cli *SomeClient) RoundTrip(r *http.Request) (*http.Response, error) { // Реализация метода… }

Приведу пример использования этого механизма: Кэширование HTTP-ответов

Представьте, что ваше веб-приложение подключается к API для получения данных, например, списка актуальных новостей. Допустим, что этот список обновляется раз в 10 минут. Если у приложения много пользователей, то отправлять много запросов к API будет не эффективно. Во-первых, данные остаются неизменными в течение 10 минут. Во-вторых, API-запросы обычно ограничены по частоте, и из-за большого количества запросов есть риск превысить лимиты. Решение этой проблемы — использовать http.RoundTripper. Можно настроить http.Client с кастомным RoundTripper, который будет выполнять следующие действия:

1. Если элемент есть в кэше:

  • HTTP-запрос не отправляется;

  • создаётся новый ответ, данные для которого берутся из кэша и помещаются в тело ответа.

2. Если элемента нет в кэше:

  • выполняется HTTP-запрос к API;

  • полученные данные сохраняются в кэше.

Реализовать данный функционал можно непосредственно в обработчике (handler), проверяя наличие элемента перед отправкой HTTP-запроса. Однако использование RoundTripper позволяет распределить обязанности более грамотно.

Начать дискуссию