Docs Request Lifecycle

Request Lifecycle

Every framework, no matter how small, defines a request lifecycle.

Understanding this lifecycle is the key to using Plumego correctly —
and to avoiding subtle bugs that only appear in production.

This document describes, step by step, what happens from the moment a request arrives to the moment a response is sent.


Why the Request Lifecycle Matters

Many problems in backend systems come from misunderstanding where things happen:

  • Logging at the wrong stage
  • Authentication running too late
  • Context values leaking across requests
  • Responses being written multiple times
  • Errors handled inconsistently

Plumego’s lifecycle is intentionally simple and explicit so that:

  • Execution order is predictable
  • Side effects are visible
  • Responsibility is clearly assigned

High-Level Overview

At a high level, every request in Plumego follows this flow:

Incoming HTTP Request
↓
net/http Server
↓
Plumego Router
↓
Middleware Chain
↓
Context Creation
↓
Handler Execution
↓
Response Written
↓
Request Ends

There are no hidden stages beyond this diagram.


Stage 1: net/http Accepts the Request

Plumego does not implement its own HTTP server.

When you call:

app.Run(":8080")

Plumego internally creates and starts a standard http.Server.

This means:

  • Connection handling follows Go’s standard behavior
  • Timeouts, cancellation, and keep-alive are handled by net/http
  • The base context.Context originates from the standard library

Plumego begins execution after the request has already entered the Go HTTP stack.


Stage 2: Routing and Handler Selection

Once the request reaches Plumego:

  1. The HTTP method is inspected
  2. The request path is matched against registered routes
  3. The corresponding handler is selected

Important characteristics:

  • Only explicitly registered routes are considered
  • Matching is deterministic and ordered
  • No reflection or annotation-based scanning is involved

If no route matches, Plumego immediately returns a 404 response.


Stage 3: Middleware Chain Execution

If middleware is registered, it executes before the handler.

Middleware in Plumego is:

  • Explicitly registered
  • Executed in a predictable order
  • Applied uniformly to matching routes

Execution order looks like this:

Request →
  Middleware A →
    Middleware B →
      Handler →
    Middleware B →
  Middleware A →
Response

Key properties:

  • Middleware can short-circuit the request
  • Middleware can modify context
  • Middleware must explicitly call the next function to continue

Nothing runs implicitly.


Stage 4: Context Creation and Scope

Before invoking the handler, Plumego creates a Context instance.

This context:

  • Wraps http.Request and http.ResponseWriter
  • Embeds context.Context
  • Exists for exactly one request
  • Is never reused or shared

Why this matters

  • Context values cannot leak between requests
  • Cancellation is request-scoped
  • Middleware and handlers operate on the same context instance

Plumego treats the context as the single unit of request state.


Stage 5: Handler Execution

The handler is where application logic begins.

In Plumego, handlers are expected to:

  • Read request data
  • Invoke domain or use-case logic
  • Write the response

Handlers should not:

  • Contain complex business rules
  • Manage global state
  • Depend deeply on framework internals

They are the boundary between HTTP and the application core.


Stage 6: Response Writing

The response is written explicitly by the handler (or middleware).

When a handler calls a response helper (for example, ctx.String):

  • Status code is set
  • Headers are written
  • Body is sent to the client

Once the response is written:

  • Further writes are ignored or rejected
  • The request lifecycle is effectively complete

Plumego does not perform post-processing on responses.


Stage 7: Request Completion

After the handler returns:

  • Control returns to the middleware chain (if any)
  • The HTTP server finalizes the request
  • The connection may be reused or closed by net/http

Plumego performs no background cleanup beyond what is required for the request.


Lifecycle Invariants

Plumego enforces several important invariants:

  • Each request has exactly one context
  • Each request executes handlers at most once
  • Middleware order is fixed and visible
  • Response writing is explicit
  • No background goroutines are spawned implicitly

These invariants are essential for reasoning about behavior under load and failure.


What the Lifecycle Does Not Include

The request lifecycle intentionally excludes:

  • Automatic retries
  • Background jobs
  • Asynchronous side effects
  • Global state mutation

If these behaviors are required, they must be implemented explicitly and consciously.


Common Mistakes to Avoid

Writing responses in multiple places

Ensure that:

  • Only one component writes the final response
  • Middleware that short-circuits does not allow the handler to continue

Performing heavy work before routing

Expensive operations should occur after route matching and authorization.


Treating middleware as business logic

Middleware should handle cross-cutting concerns only.

Business rules belong in the application core.


Why Plumego Keeps the Lifecycle Simple

Complex lifecycles are difficult to reason about and debug.

Plumego intentionally avoids:

  • Multiple handler phases
  • Implicit hooks
  • Framework-managed background tasks

Simplicity here enables flexibility elsewhere.


Summary

The Plumego request lifecycle is:

  • Linear
  • Explicit
  • Predictable
  • Closely aligned with Go’s standard library

If you understand this lifecycle, you understand Plumego’s core behavior.

Everything else in the framework builds on this foundation.


Next

With the lifecycle understood, the next step is to examine the most important building block in detail:

→ Context