Перейти на средний уровень
Контекст в программировании на Go — часть 1
Основное использование контекста — WithValue
До выхода Go 1.7 context
была внешней библиотекой golang.org/x/net/context
, а после выпуска Go 1.7 библиотека context
была добавлена как встроенная библиотека, которая позволяет другим стандартным библиотекам использовать context
для отмены, передачи данных, тайм-аут, особенно net/http
. В этой части я расскажу об использовании context
при передаче данных в области запроса.
Примечание к выпуску: Примечание к выпуску Go 1.7
Требование
- Основы программирования Go
- Перейти версии ≥ 1.7
Единственное, что вам нужно, это основы программирования на Go, канал и горутина являются необязательными, а также Go версии ≥ 1.7 Go, потому что мы будем использовать context
в качестве встроенной библиотеки.
Репозиторий: https://github.com/david-yappeter/go-context-examples
Практика
Как мы видим внутри библиотеки context
есть несколько функций:
context.Context{}
— тип контекста, который мы будем использовать.context.Background()
, обычно он используется для объявления ненулевого пустого контекста и инициализации в качестве контекста верхнего уровня (первого контекста) из запроса.context.TODO()
имеет то же значение, что иcontext.Background()
, но с другим описанием из официальной документации. Мы используем этот контекст только тогда, когда не уверены, что контекст будет использоваться или еще недоступен.context.WithValue()
принимает 3 параметра: родительский контекст, ключ и значение. Он вернетcontext.Context{}
с родительским значением и значением, которое мы установили в параметре.
Другие вещи вроде context.WithCancel()
, context.WithTimeout()
, context.WithDeadline()
будут обсуждаться в следующей части, следите за обновлениями :).
Начнем с простого примера:
Разобью на несколько частей:
- Сначала мы создаем пустой контекст и присваиваем его переменной
ctx
. - Создайте 3 контекста с
ctx
в качестве родительского значения, с его ключом и значением. - Затем мы создаем другой контекст с
ctx1
в качестве родителя и даем ему ключ и значение. - Мы попробуем извлечь значение из
ctx1
,ctx2
,ctx3
с правильным ключом. Он вернет нам значение по ключу. - Если мы попытаемся извлечь значение из контекста с неправильным ключом, оно вернет значение
nil
.
Теперь мы применим эту штуку в Rest API с библиотекой net/http
.
main.go
Например, мы создадим middleware
, который получает данные из токена и назначит значение запросу context
(middleware1)
, а позже мы будем использовать CtxClaim
для извлечения значения. Мы создадим простой прослушиватель HTTP на конечной точке /
.
http.Handle("/", …
и назначьте промежуточное ПО и http.HandlerFunc()
внутри промежуточного ПО, которые будут обрабатывать запрос. Мы настроим его на прослушивание порта 8080.
Теперь нам нужно только запустить код с go run main.go
и попытаться получить доступ к http://localhost:8080. Вывод программы:
Insert Claim into Context &{ID:1}
Это все, что касается первой части Контекст в программировании на Go. Желаем вам удачного дня :).