Passing context into a helper lets the helper read request-scoped data.

pass context Functions usually accept a context as their first parameter so callers can pass values and cancellation.

Helper Context

action
helper_context.go
Replay: real traced execution (multi-file project)
package main

import (
	"context"
	"fmt"
)

type requestKey string

func labelRequest(ctx context.Context, action string) string {
	id := ctx.Value(requestKey("id"))
	return fmt.Sprintf("%v:%s", id, action)
}

func main() {
	var action = "save"
	ctx := context.WithValue(context.Background(), requestKey("id"), "req-7")

	label := labelRequest(ctx, action)
	fmt.Println("action=", action)
	fmt.Println("label=", label)
}
package main

import (
	"context"
	"fmt"
)

type requestKey string

func labelRequest(ctx context.Context, action string) string {
	id := ctx.Value(requestKey("id"))
	return fmt.Sprintf("%v:%s", id, action)
}

func main() {
	var action = "load"
	ctx := context.WithValue(context.Background(), requestKey("id"), "req-7")

	label := labelRequest(ctx, action)
	fmt.Println("action=", action)
	fmt.Println("label=", label)
}
package main

import (
	"context"
	"fmt"
)

type requestKey string

func labelRequest(ctx context.Context, action string) string {
	id := ctx.Value(requestKey("id"))
	return fmt.Sprintf("%v:%s", id, action)
}

func main() {
	var action = "delete"
	ctx := context.WithValue(context.Background(), requestKey("id"), "req-7")

	label := labelRequest(ctx, action)
	fmt.Println("action=", action)
	fmt.Println("label=", label)
}
  1. action ← "save", ctx ← &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}

    15func main() {16  var action→ "save" = "save" //@action="load", "delete"17  ctx→ &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} := context.WithValue(context.Background(), requestKey("id"), "req-7")1819  label := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"save")20  fmt.Println("action=", action)
  2. id ← "req-7"

    10func labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} context.Context, action"save" string) string {11  id→ "req-7" := ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}.Value(requestKey("id"))12  return fmt.Sprintf("%v:%s", id"req-7", action"save")13}
  3. label ← "req-7:save"

    19  label→ "req-7:save" := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"save")20  fmt.Println("action=", action"save")21  fmt.Println("label=", label"req-7:save")22}
    outputaction= save
    label= req-7:save
  1. action ← "load", ctx ← &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}

    15func main() {16  var action→ "load" = "load"17  ctx→ &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} := context.WithValue(context.Background(), requestKey("id"), "req-7")1819  label := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"load")20  fmt.Println("action=", action)
  2. id ← "req-7"

    10func labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} context.Context, action"load" string) string {11  id→ "req-7" := ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}.Value(requestKey("id"))12  return fmt.Sprintf("%v:%s", id"req-7", action"load")13}
  3. label ← "req-7:load"

    19  label→ "req-7:load" := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"load")20  fmt.Println("action=", action"load")21  fmt.Println("label=", label"req-7:load")22}
    outputaction= load
    label= req-7:load
  1. action ← "delete", ctx ← &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}

    15func main() {16  var action→ "delete" = "delete"17  ctx→ &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} := context.WithValue(context.Background(), requestKey("id"), "req-7")1819  label := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"delete")20  fmt.Println("action=", action)
  2. id ← "req-7"

    10func labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} context.Context, action"delete" string) string {11  id→ "req-7" := ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}.Value(requestKey("id"))12  return fmt.Sprintf("%v:%s", id"req-7", action"delete")13}
  3. label ← "req-7:delete"

    19  label→ "req-7:delete" := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"delete")20  fmt.Println("action=", action"delete")21  fmt.Println("label=", label"req-7:delete")22}
    outputaction= delete
    label= req-7:delete