httpx

package module
v0.7.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2025 License: MIT Imports: 25 Imported by: 0

README

HTTPx - HTTP Extras for Go

logo

HTTPx is a collection of HTTP utilities for Go that extend the standard net/http package with commonly needed functionality for web development. It provides middlewares, request helpers, and session management to simplify building robust webapps.

Features

  • 🔄 LiveReload – Automatically reloads web pages during development using Server-Sent Events.
  • 🔎 Body Parsing – Parse request bodies into a user-defined struct, supporting JSON, XML, and form data.
  • 🪵 Logger – Log HTTP requests with customizable formats to console or any io.Writer.
  • 🏷️ ETag – Enables efficient client-side caching via automatic ETag headers.
  • Session – Secure and simple session management with cookie-based storage and pluggable backends.
  • 🧩 Mux – Grouped routing with middleware support, making it easy to organize complex HTTP routes.

Quick Start

Below is an example of using httpx.ServeMux with the Logger middleware:

package main

import (
    "fmt"
    "net/http"
    "time"

    "github.com/bluescreen10/httpx"
    "github.com/bluescreen10/httpx/logger"
)

func main() {
    // Create a new ServeMux
    mux := httpx.NewServeMux()

    // Attach Logger middleware
    mux.Use(httpx.Logger())

    // Define routes
    mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Hello, HTTPx!")
    }))

    // Start the server
    fmt.Println("Server running on http://localhost:8080")
    http.ListenAndServe(":8080", mux)
}

Documentation

Overview

Codec defines how session values and metadata (like creation time) are serialized to and from bytes, allowing them to be stored or transmitted. The package includes a default implementation using Go's `encoding/gob`.

ETag provides an HTTP middleware that calculates and sets ETag headers for GET requests. It can optionally use a cache to avoid recalculating ETags and supports weak ETags.

This middleware allows clients to make conditional requests using the If-None-Match header. When the content has not changed, the middleware responds with HTTP 304 Not Modified, saving bandwidth and improving performance.

Usage:

mux := http.NewServeMux()
mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello, world!"))
})

// Create ETag middleware (weak ETags and caching enabled)
etag := httpx.Etag()

http.ListenAndServe(":8080", etag(handler))

Only GET requests are supported. Responses for other HTTP methods are passed through unmodified.

Package livereload provides an HTTP middleware that enables live reloading of web pages by injecting a small JavaScript snippet into HTML responses. When the server restarts, connected clients automatically refresh their page.

This is particularly useful during development, as it avoids manual browser refreshes when making code or template changes.

Usage:

mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("<html><body><h1>Hello, world!</h1></body></html>"))
})

// Create a new LiveReload middleware (optional custom path)
lr := httpx.NewLiveReload()

// Wrap the mux with the middleware

http.ListenAndServe(":8080", lr.Handler(mux))

Only responses with "Content-Type: text/html" and a closing </body> tag will be modified to inject the script. Non-HTML responses pass through unmodified. Client communication is done via Server-Sent Events (SSE).

Package logger provides an HTTP middleware for logging server activity. It allows customizable log formats and output destinations.

Log entries can include variables such as time, HTTP status, latency, client IP, request method, request path, and error (currently unused).

Usage:

mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello, world!"))
})

// Create a new Logger middleware with default settings
logger := httpx.LoggerWithconfig( LoggerConfig{
	Format: ("${time} | ${status} | ${latency} | ${ip} | ${method} | ${path}\n"),
	Output: os.Stdout
})

http.ListenAndServe(":8080", logger(mux))

The middleware wraps the http.Handler, recording request start time, status code, latency, client IP, HTTP method, and path. Log entries are written to the configured output, defaulting to os.Stdout.

SessionManager provides a middleware-based session management system for HTTP servers in Go. It supports cookie-based sessions, idle timeouts, configurable persistence, and pluggable serialization codecs. Designed heavily inspired by: https://github.com/alexedwards/scs

Usage:

	package main

	import (
	    "fmt"
	    "net/http"
	    "time"

	    "github.com/bluescreen10/httpx"
	    "github.com/bluescreen10/httpx/memstore"
	)

	func main() {
	    store := memstore.New()
	    mgr := httpx.NewSessionManager(store)
        mgr.SetIdleTimeout(10 * time.Minute)

	    mux := http.NewServeMux()
	    mux.Handle("/", mgr.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	        sess := mgr.Get(r)
	        count := sess.GetInt("count")
	        count++
	        sess.Set("count", count)
	        fmt.Fprintf(w, "You have visited %d times\n", count)
	    })))

	    http.ListenAndServe(":8080", mux)
	}

Index

Constants

This section is empty.

Variables

View Source
var DefaultETagConfig = ETagConfig{}
View Source
var DefaultLoggerConfig = LoggerConfig{
	Format: "${time} | ${status} | ${latency} | ${ip} | ${method} | ${path} | ${error}\n",
	Output: os.Stdout,
}

Functions

func ParseBody

func ParseBody(r *http.Request, dst any) error

ParseBody parses the HTTP request body into the provided struct based on the Content-Type header.

Supported content types:

  • application/x-www-form-urlencoded, multipart/form-data, text/plain: Uses `form:"fieldname"` struct tags to map form fields to struct fields.
  • application/json: Uses `json` struct tags for mapping.
  • application/xml: Uses `xml` struct tags for mapping.

The dst parameter must be a pointer to a struct.

Form parsing supports these field types:

  • string
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • bool ("on"/"off", "1"/"0", "yes"/"no", "true"/"false")
  • slices of the above types

Form struct tags can specify options, e.g.:

type MyForm struct {
    Name string `form:"name,required"`
}

The only supported option currently is "required".

Returns an error if:

  • dst is not a pointer to a struct
  • content type is unsupported
  • required form fields are missing
  • conversion to the target type fails
  • request body cannot be read or parsed

Usage:

type CreateUserRequest struct {
    Name     string `form:"name,required"`
    Age      int    `form:"age"`
    Email    string `form:"email"`
    IsActive bool   `form:"is_active"`
}

func handler(w http.ResponseWriter, r *http.Request) {
    var req CreateUserRequest
    if err := httpx.ParseBody(r, &req); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    fmt.Fprintf(w, "Parsed: %+v", req)
}

Types

type Codec

type Codec interface {
	// Decode decodes byte slice into the session creation time and values.
	Decode(data []byte) (createdAt time.Time, values map[string]any, err error)

	// Encode encodes the creation time and session values into a byte slice.
	Encode(createdAt time.Time, values map[string]any) (data []byte, err error)
}

Codec is an interface for serializing and deserializing session data.

type CookieConfig

type CookieConfig struct {
	Name        string
	Path        string
	Domain      string
	Secure      bool
	HttpOnly    bool
	Partitioned bool
	SameSite    http.SameSite
	Persisted   bool
}

type ETagConfig

type ETagConfig struct {
	// Uses a cache to store ETag values for a given URL. This
	// prevents recomputing the ETag for every request.
	UseCache bool

	// Uses the prefix "W/" in the ETag header
	IsWeak bool
}

ETag Configuration

type GobCodec

type GobCodec struct{}

gobCodec is a Codec implementation using Go's encoding/gob. It serializes a gobData struct containing the creation time and session values.

func (GobCodec) Decode

func (GobCodec) Decode(data []byte) (time.Time, map[string]any, error)

Decode deserializes the data into a creation time and session values using gob decoding.

func (GobCodec) Encode

func (GobCodec) Encode(createdAt time.Time, values map[string]any) ([]byte, error)

Encode serializes the creation time and session values into a byte slice using gob encoding.

type LiveReload

type LiveReload struct {
	// contains filtered or unexported fields
}

LiveReloadConfig is the optional configuration for live reload

func NewLiveReload added in v0.7.0

func NewLiveReload() *LiveReload

LiveReload retuns a middleware that will inject a small script on the page. This script will automatically reload the page if the server sends an event, or if it gets restarted.

func (*LiveReload) Handler added in v0.7.0

func (lr *LiveReload) Handler(next http.Handler) http.Handler

LiveReloadWithConfig returns a LiveReload middleware with the specified configuration.

func (*LiveReload) Reload added in v0.7.0

func (lr *LiveReload) Reload()

Reload will trigger a reload of the current page in the browser. This can be used in combination with file watcher to force a page reload.

func (*LiveReload) SetPath added in v0.7.0

func (lr *LiveReload) SetPath(path string)

SetPath allows changing the path used for the javascript library to receive Server-Side Events (default: "/_livereload").

type LoggerConfig

type LoggerConfig struct {
	Format string
	Output io.Writer
}

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware defines the interface for HTTP middleware compatible with ServeMux.

func ETag

func ETag() Middleware

ETag returs a middleware with the default configuration that set and checks ETags headers. For GET requests, it calculates an ETag based on the response body and sets the ETag header. If the client sends If-None-Match matching the ETag, a 304 Not Modified is returned.

func ETagWithConfig

func ETagWithConfig(cfg ETagConfig) Middleware

ETagWithConfig returs am ETag middleware with the specified configuration.

func Logger

func Logger() Middleware

Logger returns a middleware with the default configuration. It logs requests using the configured format and output. It records start time, response status code, latency, client IP, HTTP method, and path.

func LoggerWithConfig

func LoggerWithConfig(cfg LoggerConfig) Middleware

LoggerWithConfig returns a Logger middleware with the specified configuration.

type Renderer added in v0.7.0

type Renderer struct {
	// contains filtered or unexported fields
}

Renderer provides efficient HTML template rendering with lazy loading and hot-reload support. Templates are loaded from an fs.FS and cached until explicitly reloaded.

Usage:

//go:embed templates
var templatesFS embed.FS

renderer := httpx.NewRenderer(templatesFS, ".html")

// Add custom template functions
renderer.Funcs(template.FuncMap{
	"upper": strings.ToUpper,
})

// Render to HTTP response
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	renderer.Html(w, "index", httpx.Vals{
		"Title": "Home",
		"User":  "Alice",
	})
})

// Hot-reload templates during development
renderer.Reload()

func NewRenderer added in v0.7.0

func NewRenderer(dir fs.FS, pattern string) *Renderer

NewRenderer creates a new Renderer that loads templates from the given filesystem matching the specified pattern (e.g., ".html", ".tmpl"). Templates are named by their path relative to the filesystem root, with the pattern suffix removed.

For example, a file at "pages/index.html" with pattern ".html" will be named "pages/index".

func (*Renderer) Funcs added in v0.7.0

func (v *Renderer) Funcs(funcs template.FuncMap)

Funcs registers custom template functions that will be available in all templates. This must be called before any templates are rendered.

func (*Renderer) Html added in v0.7.0

func (v *Renderer) Html(w http.ResponseWriter, tmpl string, vals Vals, layouts ...string) error

Html renders the named template with the given values and writes the result to the HTTP response with appropriate headers. The Content-Type is set to "text/html; charset=utf-8" and the status code is set to 200 OK.

func (*Renderer) Reload added in v0.7.0

func (v *Renderer) Reload()

Reload marks all templates as stale, forcing them to be reloaded on the next render. This is useful for development when templates are modified without restarting the application.

func (*Renderer) Render added in v0.7.0

func (v *Renderer) Render(w io.Writer, tmpl string, vals Vals, layouts ...string) error

Render executes the named template with the given values and writes the output to w. Templates are loaded lazily on first use and cached for subsequent renders. You can pass an optional template name to be used as layout (base template)

type ServeMux

type ServeMux struct {
	*http.ServeMux
	// contains filtered or unexported fields
}

ServeMux is a wrapper around http.ServeMux that adds support for route grouping and applying middlewares with syntax sugar.

Usage:

mux := httpx.NewServeMux()

// Global middleware for all routes
mux.Use(httpx.Logger())

// Route group with prefix "/api" and additional middleware
api := mux.Group("/api", authMiddleware)

// Register handlers on the group
api.HandleFunc("/users", usersHandler)
api.HandleFunc("/posts", postsHandler)

http.ListenAndServe(":8080", mux)

func NewServeMux

func NewServeMux() *ServeMux

NewServeMux creates a new ServeMux instance.

func (*ServeMux) Group

func (mux *ServeMux) Group(prefix string, middlewares ...Middleware) *ServeMux

Group creates a sub-router with the given prefix and optional middlewares. The returned sub-router can register its own handlers, which will inherit the parent middlewares automatically.

func (*ServeMux) ServeHTTP

func (mux *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler and applies global middlewares before dispatching to the underlying http.ServeMux.

func (*ServeMux) Static added in v0.7.0

func (mux *ServeMux) Static(prefix, dir string, middlewares ...Middleware)

Static mounts a file server with the give prefix and optional middlewares. The dir specifies the root of the file server.

func (*ServeMux) Use

func (mux *ServeMux) Use(middleware Middleware)

Use adds a global middleware to the ServeMux. These middlewares are applied to all routes registered on this mux.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session represents an HTTP session with associated data and configuration. It tracks creation time, modification status, and whether the session has been destroyed.

func (*Session) Clear

func (s *Session) Clear()

Clear removes all values from the session.

func (*Session) Delete

func (s *Session) Delete(key string)

Delete removes a value from the session and marks it as modified.

func (*Session) Destroy

func (s *Session) Destroy()

Destroy removes the session by clearing all values and marking it as destroyed and modified.

func (*Session) Get

func (s *Session) Get(key string) interface{}

Get retrieves a value from the session. Returns nil if the key doesn't exist.

func (*Session) GetBool

func (s *Session) GetBool(key string) bool

GetBool retrieves a bool value from the session. Returns false if not found or type mismatch.

func (*Session) GetCreatedAt

func (s *Session) GetCreatedAt() time.Time

GetCreatedAt returns the time when the session was created.

func (*Session) GetFloat32

func (s *Session) GetFloat32(key string) float32

GetFloat32 retrieves a float32 value from the session. Returns 0 if not found or type mismatch.

func (*Session) GetFloat64

func (s *Session) GetFloat64(key string) float64

GetFloat64 retrieves a float64 value from the session. Returns 0 if not found or type mismatch.

func (*Session) GetID

func (s *Session) GetID() string

GetID returns the session's unique identifier.

func (*Session) GetInt

func (s *Session) GetInt(key string) int

GetInt retrieves an int value from the session. Returns 0 if not found or type mismatch.

func (*Session) GetString

func (s *Session) GetString(key string) string

GetString retrieves a string value from the session. Returns "" if not found or type mismatch.

func (*Session) GetUint

func (s *Session) GetUint(key string) uint

GetUint retrieves a uint value from the session. Returns 0 if not found or type mismatch.

func (*Session) Set

func (s *Session) Set(key string, value interface{})

Set adds or updates a value in the session. Marks the session as modified.

func (*Session) SetWeak

func (s *Session) SetWeak(key string, value interface{})

SetWeak adds or updates a value in the session but doesn't set the isModified flag. This is useful for values that are ok if they are not saved.

type SessionManager

type SessionManager struct {
	// contains filtered or unexported fields
}

SessionManager manages HTTP sessions using a Store backend and session options.

func NewSessionManager

func NewSessionManager(store Store) *SessionManager

NewSessionManager returns a middleware-based session management stores session data in a Store backend, manages cookies, handles idle timeouts, and provides a load/save workflow automatically via the Handler middleware interface.

func (*SessionManager) Get

func (m *SessionManager) Get(r *http.Request) *Session

Get retrieves the current session from the request context. This should be used only when using the middleware (Handler method).

func (*SessionManager) Handler

func (m *SessionManager) Handler(next http.Handler) http.Handler

Handler method is a middleware that provides load-and-save session functionality. It ensures that the session is loaded from the store and saved after the request.

func (*SessionManager) Load

func (m *SessionManager) Load(token string) (*Session, error)

Load retrieves a session from the store by token. If the token is empty or the session is not found, a new session is created.

func (*SessionManager) Save

func (m *SessionManager) Save(w http.ResponseWriter, sess *Session) error

Save persists the session to the store and updates the HTTP cookie. Destroyed sessions are deleted from the store and expired cookies are set.

func (*SessionManager) SetCookieConfig

func (m *SessionManager) SetCookieConfig(cfg CookieConfig)

func (*SessionManager) SetIdleTimeout

func (m *SessionManager) SetIdleTimeout(timeout time.Duration)

func (*SessionManager) SetLifetime

func (m *SessionManager) SetLifetime(lifetime time.Duration)

type Store

type Store interface {
	// Get retrieves the session data associated with the given token.
	// It returns the raw session data, a boolean indicating whether
	// the session was found, and an error if the lookup failed.
	Get(token string) (data []byte, found bool, err error)

	// Set stores the session data for the given token until the
	// specified expiration time. If a session with the same token
	// already exists, it should be overwritten.
	Set(token string, data []byte, expiresAt time.Time) error

	// Delete removes the session associated with the given token.
	// It returns an error if the deletion fails, but should not
	// return an error if the session does not exist.
	Delete(token string) error
}

Store defines the interface for session storage backends. A Store is responsible for persisting and retrieving session data by a unique session token. Implementations may store sessions in memory, databases, caches, or any other durable storage system.

type Vals added in v0.7.0

type Vals map[string]any

Vals is a convenience type for passing data to templates.

Directories

Path Synopsis
gormstore module
memstore module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL