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.Requestandhttp.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.
Recommended usage
- 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.