Docs Context

Context

In Plumego, Context is the central unit of request state.

Every handler and middleware receives a *plumego.Context.
Understanding what this context is — and what it is not — is critical to using Plumego correctly.


Why Plumego Has Its Own Context

Go already provides context.Context.

Plumego does not replace it.

Instead, Plumego introduces a thin wrapper that:

  • Embeds context.Context
  • Wraps http.Request and http.ResponseWriter
  • Provides common request/response helpers
  • Defines a clear boundary between framework and application code

The goal is not abstraction for its own sake, but clarity and consistency.


What a Plumego Context Contains

A plumego.Context typically includes:

  • The underlying context.Context
  • The incoming *http.Request
  • The http.ResponseWriter
  • Request-scoped values
  • Response helpers

All of this exists only for the lifetime of a single request.


Request Scope and Lifetime

Each incoming HTTP request creates exactly one Context instance.

Key properties:

  • Context is created after routing, before middleware/handler execution
  • Context is never shared between requests
  • Context is never reused
  • Context is discarded immediately after the request completes

This strict lifecycle prevents:

  • Data leakage across requests
  • Accidental reuse of state
  • Subtle concurrency bugs

Context and Cancellation

Plumego’s context embeds Go’s context.Context.

This means:

  • Cancellation propagates naturally from net/http
  • Timeouts set on the HTTP server are respected
  • Downstream operations can listen for ctx.Done()

Example:

select {
case <-ctx.Done():
	// request cancelled
case result := <-work:
	// continue
}

Plumego does not modify or delay cancellation behavior.


Context as the Request Boundary

Plumego treats Context as the boundary between HTTP and application logic.

Handlers and middleware should:

  • Read request data from the context
  • Write responses through the context
  • Pass only necessary data to domain logic

Domain code should not depend on plumego.Context.

This separation is essential for:

  • Testability
  • Reusability
  • Future transport changes

Storing Values in Context

Plumego allows request-scoped values to be stored in the context.

Common examples include:

  • Authentication information
  • Trace IDs
  • Request metadata

However, this must be done with discipline.

  • Store small, immutable values
  • Use well-defined keys
  • Set values in middleware, not handlers

Anti-patterns

  • Storing large objects
  • Using context as a general-purpose container
  • Passing business entities through context

Context is not a dependency injection mechanism.


Reading and Writing Responses

Plumego provides helpers on the context to write responses.

For example:

ctx.String(http.StatusOK, "OK")

Key principles:

  • Responses are written explicitly
  • The first write finalizes headers
  • Writing multiple responses is an error

Plumego does not automatically serialize data or infer formats.


Context Is Not Global State

A common mistake is treating context as global storage.

Plumego strongly discourages:

  • Accessing context from goroutines that outlive the request
  • Storing context in global variables
  • Using context as a cache

Once the request ends, the context is invalid.


Concurrency and Context Safety

Within a request:

  • The context may be passed to concurrent operations
  • Access must be synchronized if values are mutable

Across requests:

  • Context must never be shared

Plumego does not add additional concurrency guarantees beyond Go’s standard rules.


Context and Middleware

Middleware operates on the same context instance as the handler.

This allows middleware to:

  • Enrich the context
  • Perform authorization
  • Short-circuit requests

Middleware should treat context as shared request state, not private storage.


What Context Deliberately Does Not Do

Plumego’s context does not:

  • Automatically bind request parameters
  • Perform validation
  • Handle errors implicitly
  • Manage transactions
  • Act as a service locator

These responsibilities belong elsewhere.


Common Mistakes

Passing Context into Domain Logic

Instead of:

usecase.Do(ctx)

Prefer:

usecase.Do(ctx.UserID())

Keep framework-specific types at the boundary.


Launching Goroutines Without Cancellation Awareness

If you start goroutines, always respect ctx.Done().

Failure to do so leads to resource leaks.


Summary

Plumego’s Context is:

  • Request-scoped
  • Explicit
  • Predictable
  • Minimal by design

It exists to clarify the request boundary, not to hide complexity.

Used correctly, it becomes a powerful tool for building reliable systems.

Used incorrectly, it becomes a source of subtle bugs.


Next

With Context understood, the next concept is:

→ Middleware

This explains how cross-cutting concerns interact with the request lifecycle.