HTTPとデータベース呼び出しにおけるContext
呼び出しチェーン全体にコンテキストを伝播させます。
「HTTPとデータベース呼び出しにおけるContext」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
コンテキストを使う HTTP クライアント
req.WithContext(ctx) を使って、送信する HTTP リクエストにコンテキストを渡します。レスポンスが返る前にコンテキストがキャンセルされると、リクエストもキャンセルされます。
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
リクエストを作成してから WithContext を呼び出すよりも、http.NewRequestWithContext(Go 1.13 以降)を使用してください。こちらのほうが簡潔で、中間的な割り当ても避けられます。
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)
}ミドルウェアチェーンでのコンテキスト
ミドルウェアは、デッドライン、認証データ、トレース ID などでリクエストコンテキストを拡張し、拡張したリクエストを次のハンドラーに渡します。
サービス呼び出し間でのコンテキストの伝播
マイクロサービスアーキテクチャでは、受信リクエストのコンテキストに含まれるトレース ID を、送信するすべての HTTP ヘッダーと RPC ヘッダーに挿入する必要があります。これにより、分散トレーシングがエンドツーエンドで機能します。
コンテキストを使ったテスト
テストでは、テストケース間で goroutine がリークするのを防ぐため、context.Background() または context.WithTimeout を使用します。
クイックチェック
コンテキストが付加された HTTP リクエストを作成する関数はどれですか。
まとめ: HTTP と DB でのコンテキスト
要点:
- 送信する HTTP 呼び出しには http.NewRequestWithContext を使用します
- database/sql の *Context メソッドは、コンテキストが完了するとクエリをキャンセルします
- 受信リクエストでは r.Context() を使用し、クライアント切断時にキャンセルされます
- すべての下流呼び出しにコンテキスト(およびトレース ID)を伝播させます
よくある質問
「HTTPとデータベース呼び出しにおけるContext」レッスンは無料ですか?
はい。「HTTPとデータベース呼び出しにおけるContext」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「HTTPとデータベース呼び出しにおけるContext」で何を学びますか?
呼び出しチェーン全体にコンテキストを伝播させます。 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「HTTPとデータベース呼び出しにおけるContext」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- context.Contextが存在する理由
- WithCancelとWithTimeout
- WithDeadlineとWithValue
- HTTPとデータベース呼び出しにおけるContext