NetLife Guru

Open source Go packages for fast, maintainable web systems. Built with a documentation-first approach.

Product
OverviewGolang packagesNews
Documentation
DocumentationGo LoggerGo RouterGo DB Form
Company
OverviewContactNewsGitHub
Community / Support
Supportinfo@netlife.guru
© 2026 NetLife Guru. All rights reserved.
GitHubinfo@netlife.guru
NetLife GuruNetLife GuruNetLife Guru
NetLife GuruNetLife GuruNetLife Guru
OverviewDocumentationNewsSupportContact

Golang packages

About
PerformanceArchitectureRequest LifecycleGraceful Shutdown
RouterAdvanced

Request Lifecycle

Understand how an HTTP request moves through the router, from route matching and middleware execution to handler response and context cleanup.

The request lifecycle describes what happens when an HTTP request enters the router.

Understanding this flow helps when working with:

  • middleware order
  • request logging
  • route parameters
  • recovery handling
  • request-scoped context
  • response behavior

Lifecycle Overview

incoming HTTP request
↓
request context allocation
↓
route matching
↓
method validation
↓
middleware chain
↓
handler execution
↓
response writing
↓
panic recovery, if needed
↓
context cleanup

1. Incoming Request

Every request starts as a standard Go HTTP request:

*http.Request

The router is compatible with Go’s net/http ecosystem and can be used anywhere an http.Handler is expected.


2. Request Context

Before routing continues, the router prepares a request-scoped *router.Context.

This context is used for:

  • route parameters
  • temporary request values
  • middleware-to-handler communication
func(w http.ResponseWriter, req *http.Request, ctx *router.Context)

The context exists only for the lifetime of the request.


3. Route Matching

The router attempts to match the request path against registered routes.

It supports:

  • static routes
  • parameterized routes
  • wildcard routes
  • mounted handlers
  • grouped routes

Example:

r.GET("/users/{id}", handler)

Request:

GET /users/42

Captured parameter:

id = 42

4. Method Validation

After the path is matched, the router validates the HTTP method.

Example:

r.HandleFunc("/documents", "GET POST", handler)

Allowed methods:

GET
POST

If the path exists but the method is not allowed, the router returns:

405 Method Not Allowed

5. Middleware Execution

Before the handler runs, middleware is executed.

Middleware can be registered globally:

r.Use(router.RequestID())

or on route groups:

api.Use(AuthMiddleware)

Middleware can run logic before and after the next handler:

r.Use(func(next router.HandlerFunc) router.HandlerFunc {
	return func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		// before handler

		next(w, req, ctx)

		// after handler
	}
})

6. Handler Execution

If the route and method match, the final handler is executed.

r.GET("/users/{id}", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
	id := ctx.Param("id")

	w.Write([]byte(id))
})

The handler can:

  • read request data
  • access route parameters
  • read or write context values
  • write headers
  • write the response body

7. Response Writing

Handlers write responses using the standard http.ResponseWriter.

Example:

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"ok"}`))

Because the router uses standard Go HTTP primitives, response behavior follows normal net/http rules.


8. Panic Recovery

If a handler panics, the router can recover and return a controlled response.

r.Recovery(func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
	w.WriteHeader(http.StatusInternalServerError)
	w.Write([]byte("Internal Server Error"))
})

If no custom recovery handler is configured, the router returns a standard internal server error response.

Recovered panics are logged through Go’s log/slog ecosystem.


9. Context Cleanup

After the request completes, the router releases the request context.

The context is reused internally to reduce allocations.

Applications should not store *router.Context beyond the request lifecycle.

Incorrect:

saved = ctx

Correct:

userID := ctx.Get("user_id")

Copy the value you need instead of keeping the context itself.


Middleware Order

Middleware order is important.

Middleware is applied in the order it is registered:

r.Use(A)
r.Use(B)
r.Use(C)

Execution flow:

A before
↓
B before
↓
C before
↓
handler
↓
C after
↓
B after
↓
A after

This allows middleware to wrap behavior around later middleware and handlers.


Example Flow

For this route:

r.Use(router.RequestID())
r.Use(router.Logger())

r.GET("/users/{id}", handler)

Request:

GET /users/42

Lifecycle:

request received
↓
context prepared
↓
route /users/{id} matched
↓
id parameter extracted
↓
RequestID middleware runs
↓
Logger middleware starts timer
↓
handler executes
↓
Logger middleware writes request log
↓
context released

Notes

The router keeps the request lifecycle explicit.

Routing, middleware, logging, recovery, and response writing remain separate concerns, making application behavior easier to understand, test, and debug.

Architecture

Understand how the router is structured internally, including route matching, middleware execution, context pooling, method matching, and standard library compatibility.

Graceful Shutdown

Gracefully stop HTTP servers, finish active requests, and safely release resources during application shutdown.

On this page

Lifecycle Overview1. Incoming Request2. Request Context3. Route Matching4. Method Validation5. Middleware Execution6. Handler Execution7. Response Writing8. Panic Recovery9. Context CleanupMiddleware OrderExample FlowNotes