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
Route HandlersParameterized RoutesWildcard RoutesRoute GroupsMiddlewareGroup MiddlewareMounting Standard HandlersRequest Context
RouterCore Concepts

Request Context

Store request-scoped values, access route parameters, and share data safely between middleware and handlers using router.Context.

The router package provides a lightweight request-scoped context through *router.Context.

func(w http.ResponseWriter, req *http.Request, ctx *router.Context)

The context is designed for:

  • route parameters
  • middleware communication
  • request-scoped storage
  • authentication data
  • database connections
  • tracing metadata
  • reusable request state

The context exists only for the lifetime of the request.


Accessing Route Parameters

Route parameters can be accessed using ctx.Param.

Example route:

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

Handler:

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

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

Request:

/users/42

Captured value:

42

Storing Request Values

Middleware and handlers can store values inside the request context.

ctx.Set("user_id", 42)

Later in the request lifecycle:

userID := ctx.Get("user_id")

This allows middleware and handlers to share request-scoped state safely.


Example

package main

import (
	"net/http"

	"github.com/netlifeguru/router"
)

func main() {
	r := router.New()

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

			ctx.Set("request_source", "middleware")

			next(w, req, ctx)
		}
	})

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

		source := ctx.Get("request_source")

		w.Write([]byte(
			"user_id=" + id + ", source=" + source.(string),
		))
	})

	r.ListenAndServe(":8000")
}

Request:

/users/42

Response:

user_id=42, source=middleware

Middleware Communication

One of the primary uses of router.Context is communication between middleware and handlers.

Example authentication middleware:

func Auth(next router.HandlerFunc) router.HandlerFunc {
	return func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {

		ctx.Set("user_id", 123)

		next(w, req, ctx)
	}
}

Handler:

r.GET("/profile", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
	userID := ctx.Get("user_id")

	w.Write([]byte(fmt.Sprintf("user=%v", userID)))
})

This avoids repeatedly parsing authentication state in every handler.


Request-Scoped Storage

The request context is isolated per request.

Values stored inside one request are never shared with other requests.

This makes it safe for concurrent workloads and HTTP servers handling many requests simultaneously.

Example use cases:

Use CaseExample
Authenticationuser_id, roles
Database Connectionrequest transaction
Request Tracingrequest ID
Localizationlanguage settings
Feature Flagsrequest-specific flags
Metricstiming metadata

Context Lifecycle

The context exists only while the request is being processed.

After the request completes, the context is automatically released and reused internally by the router.

Applications should never store references to *router.Context outside the request lifecycle.

Incorrect:

globalCtx = ctx

Correct:

value := ctx.Get("key")

and copy only the required values.


Performance

The request context is internally pooled to reduce allocations during high request throughput.

This helps minimize:

  • heap allocations
  • GC pressure
  • per-request overhead

The pooling mechanism is fully automatic and transparent to applications.


Context vs context.Context

router.Context is separate from Go’s standard:

context.Context

The router context is optimized for:

  • route parameters
  • request-scoped mutable values
  • middleware communication

For cancellation, deadlines, or propagation across services, continue using:

req.Context()

Both can be used together.

Example:

ctx.Set("user_id", 42)

requestCtx := req.Context()

Notes

router.Context is designed for lightweight request-scoped data sharing inside the HTTP pipeline.

It should not replace application services, dependency injection, or persistent storage.

Mounting Standard Handlers

Mount native net/http handlers, third-party services, and wildcard routes directly into the router without using router.Context.

Logging

Configure router request logging for local development and production using Go slog and the NLG Logger package.

On this page

Accessing Route ParametersStoring Request ValuesExampleMiddleware CommunicationRequest-Scoped StorageContext LifecyclePerformanceContext vs context.ContextNotes