Docs Response

Response

In Plumego, responses are not abstracted away.

There is no response pipeline,
no implicit serialization layer,
no automatic error-to-response mapping.

This is intentional.

Plumego follows a strict rule:

The framework controls request flow.
The application controls the response.

This document explains what Plumego guarantees about responses —
and what remains firmly under your control.


Response Ownership

In Plumego:

  • Handlers own the response
  • Middleware may short-circuit the response
  • The framework never generates business responses automatically

If a response is written, it is because your code wrote it.

There are no hidden defaults.


Response Is an HTTP Concept

Plumego does not redefine HTTP semantics.

Responses are written using:

  • http.ResponseWriter
  • Standard HTTP status codes
  • Standard headers
  • Standard body semantics

Plumego does not wrap or replace Go’s HTTP response model.


How Responses Are Written

Handlers interact with the response through the Context.

Conceptually:

ctx.ResponseWriter().WriteHeader(http.StatusOK)
ctx.ResponseWriter().Write(body)

Or via convenience helpers:

ctx.JSON(http.StatusOK, payload)
ctx.Text(http.StatusNotFound, "not found")

These helpers are thin conveniences, not a response framework.


Exactly One Response per Request

Plumego guarantees:

At most one response is written per request.

This is enforced by HTTP semantics, not by hidden framework logic.

Once a response is written:

  • Headers are sent
  • Status code is fixed
  • The body stream begins

Handlers and middleware must respect this.


Middleware and Responses

Middleware may write responses in specific situations:

  • Authentication failure
  • Rate limiting
  • Invalid signatures
  • Panic recovery

In these cases:

  • Middleware writes the response
  • Middleware does not call next()
  • Handler is never invoked

This is explicit control flow, not interception magic.


Response Timing

Response timing is fully controlled by your code.

A response is considered complete when:

  • Handler returns
  • Middleware “after” phase completes
  • Control returns to the HTTP server

Plumego does not flush, buffer, or retry responses implicitly.


Response Helpers Are Optional

Plumego may provide helpers such as:

  • ctx.JSON
  • ctx.Text
  • ctx.Status

These helpers:

  • Reduce boilerplate
  • Improve readability
  • Do not hide behavior

You are always free to bypass them and use http.ResponseWriter directly.


JSON Serialization Is Explicit

Plumego does not auto-serialize return values.

There is no concept of:

return object

Instead:

ctx.JSON(http.StatusOK, object)

This ensures:

  • Serialization is visible
  • Errors are handled explicitly
  • Performance characteristics are clear

Implicit serialization hides too much.


Error Responses Are Not Automatic

Plumego does not convert errors into responses automatically.

This is a deliberate design choice.

Why:

  • Error meaning is application-specific
  • Mapping errors to status codes is a policy decision
  • Automatic mapping hides intent

Handlers (or explicit helpers) must translate errors to responses.


Response and Error Boundaries

A critical rule:

Domain and usecase layers never write responses.

They return values and errors.

Only boundary layers (handlers, middleware) write responses.

If a domain object writes a response, architecture is broken.


Streaming and Advanced Responses

Because Plumego exposes the raw http.ResponseWriter, you can:

  • Stream responses
  • Write chunked bodies
  • Upgrade connections (WebSocket)
  • Use SSE
  • Control flushing

Plumego does not interfere with advanced HTTP usage.


Response Headers

Handlers and middleware may set headers explicitly:

ctx.ResponseWriter().Header().Set("X-Trace-ID", traceID)

There are no hidden headers added by the framework.

If a header exists, it came from your code.


Response and Testing

Because responses are explicit:

  • Handler tests can assert status codes
  • Headers can be inspected
  • Bodies can be parsed
  • No framework magic needs to be mocked

Example:

rec := httptest.NewRecorder()
app.ServeHTTP(rec, req)

if rec.Code != http.StatusOK {
	t.Fatalf("unexpected status: %d", rec.Code)
}

Testing mirrors production behavior closely.


Common Anti-Patterns

Returning Values Instead of Writing Responses

Plumego is not an MVC framework.

Handlers do not “return responses”.


Writing Responses in Multiple Places

This leads to partial writes and undefined behavior.


Letting Middleware Mutate Business Responses

Middleware should gate or decorate responses,
not decide business outcomes.


Why Plumego Keeps Responses Explicit

Many frameworks try to “simplify” responses.

They often end up:

  • Hiding status codes
  • Hiding serialization errors
  • Enforcing response schemas
  • Reducing flexibility

Plumego chooses explicitness instead.

What you write is what the client gets.


Summary

In Plumego:

  • Responses are explicit
  • Handlers own response writing
  • Middleware may short-circuit intentionally
  • No automatic error-to-response mapping exists
  • HTTP semantics are preserved
  • Nothing is hidden

Response handling is not abstracted —
because abstraction here costs more than it saves.


Next

With Response covered, the Core layer now fully describes:

  • Request entry
  • Lifecycle
  • Context
  • Routing
  • Middleware
  • Server integration
  • Response writing

From here, the natural next step is:

Reference (API-level documentation)
or
Examples (a complete, runnable Plumego service)

You can directly choose the next direction.