mig

package module
v0.0.0-...-b126d1a Latest Latest
Warning

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

Go to latest
Published: Nov 20, 2025 License: MIT Imports: 17 Imported by: 0

README

Mig

A small web framework for Go, built on the modern net/http.ServeMux (Go 1.22+).

mig provides a cleaner API for common web development tasks (routing, middleware, request handling) without unnecessary complexity or third-party dependencies.

Build Status Go Reference Go Report Card Go Version

Features

  • Router: Uses stdlib http.ServeMux (Go 1.22+)
  • API: Verb-based helpers (GET, POST, etc.) and route grouping with prefixes.
  • Middleware: Standard func(Handler) Handler pattern.
  • Context: Request-scoped Context object (pooled via sync.Pool) with helpers for JSON binding, responses, and path/query access.
  • Error Handling: Unified error type, panic recovery, JSON or plain text responses.
  • Shutdown: Helpers for graceful shutdown on SIGINT / SIGTERM.
  • Dependencies: None (only standard library).

Quick Start

Create a main.go file with the following code:

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/levmv/mig"
	"github.com/levmv/mig/middleware"
)

func main() {
	// 1. Initialize Mig with a background context.
	m := mig.New(context.Background())

	// 2. Register global middleware.
	// These will run for every request.
	m.Use(middleware.RequestID())
	m.Use(middleware.RequestLogger())

	// 3. Define your routes and handlers.
	m.GET("/", func(c *mig.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})

	// Route with a path parameter.
	m.GET("/users/{id}", func(c *mig.Context) error {
		id := c.PathValue("id")
		return c.JSON(map[string]string{"user_id": id})
	})

	// 4. Create a route group for better organization.
	api := m.Group("/api")
	api.GET("/status", func(c *mig.Context) error {
		return c.JSON(map[string]string{"status": "ok"})
	})

	// 5. Start the server. Run() blocks until a shutdown signal is received.
	fmt.Println("Server starting on http://localhost:8080")
	if err := m.Run(":8080"); err != nil {
		fmt.Printf("Server failed to start: %v\n", err)
	}
}

Installation

go get github.com/levmv/mig

License

This project is licensed under the MIT License.

Documentation

Overview

Package mig implements simple golang web framework.

Index

Constants

View Source
const RequestIDHeader = "X-Request-ID"

RequestIDHeader is the name of the HTTP header used for the request ID.

Variables

ErrNotFound is a standard HTTP 404 error. To create a custom 404 handler, register `m.Any("/", ...)` last.

Functions

func RequestIDFromContext

func RequestIDFromContext(ctx context.Context) string

RequestIDFromContext extracts a request ID from a stdlib context.Context.

Types

type Context

type Context struct {
	Request  *http.Request
	Response *Response
	Logger   *slog.Logger
	Mig      *Mig
	// contains filtered or unexported fields
}

Context represents the context of an HTTP request. It provides methods to access request data and send responses.

WARNING: A Context is created for each incoming request and is reused via a sync.Pool. For this reason, a Context is only valid for the lifetime of a request. It MUST NOT be stored or used across multiple goroutines. Doing so will lead to data races and unpredictable behavior, such as reading data from another request. For background operations, extract needed values first.

func (*Context) BindJSON

func (c *Context) BindJSON(out any) error

func (*Context) Get

func (c *Context) Get(name any) any

Get retrieves a value from the context.

func (*Context) HTML

func (c *Context) HTML(html string) error

func (*Context) HasQueryParam

func (c *Context) HasQueryParam(name string) bool

HasQueryParam reports whether the given query parameter exists at all.

func (*Context) JSON

func (c *Context) JSON(out any) error

func (*Context) NoContent

func (c *Context) NoContent(code int) error

NoContent sends an empty response with the given status code.

func (*Context) PathValue

func (c *Context) PathValue(name string) string

PathValue returns the value of a URL path parameter by its name. For example, for a route registered as "/users/{id}", PathValue("id") will return the corresponding value from the request URL.

func (*Context) Put

func (c *Context) Put(name any, value any)

Put stores a value in the context for the current request.

func (*Context) QueryParam

func (c *Context) QueryParam(name string, def string) string

QueryParam returns a query parameter value. If the parameter is missing, it returns the provided default. If the parameter is present but empty (?foo=), it returns the empty string.

func (*Context) Raw

func (c *Context) Raw(data []byte) error

Raw sends a raw response without setting content type.

func (*Context) Redirect

func (c *Context) Redirect(code int, url string) error

Redirect sends an HTTP redirect response.

func (*Context) RequestID

func (c *Context) RequestID() string

RequestID returns the request ID, or "" if none set.

func (*Context) Reset

func (c *Context) Reset(r *http.Request, rw http.ResponseWriter)

Reset reuses the context instance for a new request.

func (*Context) SetRequestID

func (c *Context) SetRequestID(id string)

SetRequestID attaches the request ID to this Context, its Request.Context, and the response header.

func (*Context) String

func (c *Context) String(code int, s string) error

String sends a plain text response with a given status code.

func (*Context) View

func (c *Context) View(name string, data any) error

type HTTPError

type HTTPError struct {
	Code     int    `json:"code"`
	Message  string `json:"message"`
	Internal error  `json:"-"`
	Stack    string `json:"-"`
}

HTTPError represents an error happened while handling request.

func NewHTTPError

func NewHTTPError(code int) *HTTPError

func (*HTTPError) Error

func (e *HTTPError) Error() string

func (*HTTPError) Unwrap

func (e *HTTPError) Unwrap() error

type HTTPErrorHandler

type HTTPErrorHandler func(error, *Context)

type Handler

type Handler func(*Context) error

type MiddlewareFunc

type MiddlewareFunc func(Handler) Handler

type Mig

type Mig struct {
	RouteGroup
	Mux    *http.ServeMux
	BindTo string
	// ErrorHandler is used to process any errors during requests.
	// By default, DefaultErrorHandler() is used
	ErrorHandler HTTPErrorHandler
	Logger       *slog.Logger
	Renderer     Renderer

	ShutdownTimeout time.Duration
	// Request
	ReadTimeout       time.Duration
	ReadHeaderTimeout time.Duration
	WriteTimeout      time.Duration
	IdleTimeout       time.Duration
	// contains filtered or unexported fields
}

Mig is the core framework instance that handles HTTP requests and routing.

func New

func New(ctx context.Context) *Mig

func (*Mig) DefaultErrorHandler

func (m *Mig) DefaultErrorHandler(err error, ctx *Context)

func (*Mig) Execute

func (m *Mig) Execute(handler Handler, rw http.ResponseWriter, r *http.Request)

func (*Mig) Run

func (m *Mig) Run(addr string) error

Run starts the server, blocks until an OS signal is received, and then performs a graceful shutdown. This is the simplest way to run the server.

func (*Mig) Shutdown

func (m *Mig) Shutdown() error

Shutdown gracefully stops the HTTP server. It waits for the duration of ShutdownTimeout for existing connections to finish.

func (*Mig) Start

func (m *Mig) Start(addr string) error

Start begins listening for HTTP requests in a separate goroutine. It is a non-blocking method. Use the Shutdown method to stop the server.

type Renderer

type Renderer interface {
	Render(io.Writer, string, any) error
}

Renderer is an interface for rendering templates.

type Response

type Response struct {
	http.ResponseWriter
	// contains filtered or unexported fields
}

Response wraps http.ResponseWriter and tracks status and bytes written. It implements http.ResponseWriter and can be used anywhere a ResponseWriter is expected.

func (*Response) Status

func (w *Response) Status() int

func (*Response) Write

func (w *Response) Write(b []byte) (int, error)

func (*Response) WriteHeader

func (w *Response) WriteHeader(code int)

func (*Response) Written

func (w *Response) Written() int

type RouteGroup

type RouteGroup struct {
	Mig    *Mig
	Prefix string

	ParentRouter *RouteGroup
	// contains filtered or unexported fields
}

RouteGroup represents a group of routes with shared middleware.

func (*RouteGroup) Any

func (rg *RouteGroup) Any(path string, handler Handler)

Any registers a handler that matches any HTTP method for a path.

func (*RouteGroup) DELETE

func (rg *RouteGroup) DELETE(path string, handler Handler)

DELETE registers a DELETE handler for a path.

func (*RouteGroup) GET

func (rg *RouteGroup) GET(path string, handler Handler)

GET registers a GET and HEAD handler for a path.

func (*RouteGroup) Group

func (rg *RouteGroup) Group(prefix string, middlewares ...MiddlewareFunc) *RouteGroup

Group creates a new routing group with a common prefix and shared middleware.

func (*RouteGroup) Handle

func (rg *RouteGroup) Handle(method, path string, handler Handler)

Handle registers a handler for a given HTTP method and path. It correctly applies the group's path prefix.

func (*RouteGroup) HandleRaw

func (rg *RouteGroup) HandleRaw(pattern string, handler Handler)

HandleRaw registers a handler for a raw, unprocessed http.ServeMux pattern. The group's path prefix is NOT applied. All group middleware is applied. This is the advanced method for use cases like host-based routing.

func (*RouteGroup) POST

func (rg *RouteGroup) POST(path string, handler Handler)

POST registers a POST handler for a path.

func (*RouteGroup) PUT

func (rg *RouteGroup) PUT(path string, handler Handler)

PUT registers a PUT handler for a path.

func (*RouteGroup) Use

func (rg *RouteGroup) Use(middlewares ...MiddlewareFunc)

Use adds middleware to the route group.

Directories

Path Synopsis
Package render provides default implementations of the mig.Renderer interface for Go's standard template engines.
Package render provides default implementations of the mig.Renderer interface for Go's standard template engines.

Jump to

Keyboard shortcuts

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