Go Academy · Урок

Контекст в HTTP- и вызовах к базе данных

Передача контекста по цепочке вызовов

Урок 4 из 413 шагов

«Контекст в HTTP- и вызовах к базе данных» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

HTTP-клиент с контекстом

Передавайте контекст исходящему HTTP-запросу с помощью req.WithContext(ctx). Запрос отменяется, если контекст отменён до получения ответа.

req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        // timeout
    }
}

http.NewRequestWithContext

Предпочитайте http.NewRequestWithContext (Go 1.13+) созданию запроса с последующим вызовом WithContext: этот способ чище и не требует промежуточного выделения памяти.

Отмена HTTP-запроса

Создайте отменяемый контекст с помощью WithCancel, передайте его запросу и вызовите cancel после завершения или при возникновении ошибки. Клиент прерывает TCP-соединение.

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)

database/sql с контекстом

Все методы database/sql имеют варианты с суффиксом *Context: QueryContext, ExecContext, PrepareContext. Они отменяют запрос, когда работа с контекстом завершается.

rows, err := db.QueryContext(ctx, "SELECT id FROM users WHERE active = $1", true)
if err != nil { return err }
defer rows.Close()

Проверка контекста перед запросом

Проверяйте контекст перед запуском долгого запроса, чтобы немедленно завершить выполнение, если запрос уже отменён.

if err := ctx.Err(); err != nil {
    return err // context already done
}
rows, err := db.QueryContext(ctx, ...)

Контекст и пул соединений

Если контекст отменён во время выполнения запроса, database/sql помечает соединение как неисправное, когда драйвер это поддерживает. Это не позволяет вернуть повреждённое соединение в пул.

gRPC и контекст

gRPC использует контекст для передачи крайнего срока. Клиент задаёт крайний срок контекста, а сервер проверяет его при получении каждого элемента потока. Метаданные также передаются через контекст.

resp, err := client.GetUser(ctx, &pb.GetUserRequest{Id: id})

Контекст входящего запроса

HTTP-сервер добавляет контекст к каждому входящему запросу с помощью r.Context(). Этот контекст отменяется, когда клиент отключается.

func handler(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    result, err := db.QueryContext(ctx, query)
}

Контекст в цепочках промежуточного ПО

Промежуточное ПО дополняет контекст запроса крайними сроками, данными Auth или идентификаторами трассировки, а затем передаёт дополненный запрос следующему обработчику.

Передача контекста через вызовы служб

В микросервисной архитектуре идентификатор трассировки из контекста входящего запроса следует добавлять во все исходящие заголовки HTTP и RPC, чтобы распределённая трассировка работала от начала до конца.

Тестирование с контекстом

В тестах используйте context.Background() или context.WithTimeout, чтобы горутины не оставались выполняться между тестовыми случаями.

Быстрая проверка

Какая функция создаёт HTTP-запрос с присоединённым контекстом?

Итоги: контекст в HTTP и базе данных

Основные положения:

  • Используйте http.NewRequestWithContext для исходящих HTTP-вызовов
  • Методы database/sql с суффиксом *Context отменяют запросы после завершения работы с контекстом
  • У входящих запросов используйте r.Context(); контекст отменяется при отключении клиента
  • Передавайте контекст и идентификатор трассировки во все последующие вызовы
Можно начать бесплатно

Изучай Go с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
51
Уроки
203

Часто задаваемые вопросы

Урок «Контекст в HTTP- и вызовах к базе данных» бесплатный?

Да — полный текст урока «Контекст в HTTP- и вызовах к базе данных» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Контекст в HTTP- и вызовах к базе данных»?

Передача контекста по цепочке вызовов Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Контекст в HTTP- и вызовах к базе данных»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужен context.Context
  2. WithCancel и WithTimeout
  3. WithDeadline и WithValue
  4. Контекст в HTTP- и вызовах к базе данных
← Назад к Go Academy