157 lines
4.2 KiB
Go
157 lines
4.2 KiB
Go
// Package hws provides a lightweight HTTP web server framework built on top of Go's standard library.
|
|
//
|
|
// HWS (H Web Server) is an opinionated framework that leverages Go 1.22+ routing patterns
|
|
// with built-in middleware, structured error handling, and production-ready defaults. It
|
|
// integrates seamlessly with other golib packages like hlog for logging and hwsauth for
|
|
// authentication.
|
|
//
|
|
// # Basic Usage
|
|
//
|
|
// Create a server with environment-based configuration:
|
|
//
|
|
// cfg, err := hws.ConfigFromEnv()
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
//
|
|
// server, err := hws.NewServer(cfg)
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
//
|
|
// routes := []hws.Route{
|
|
// {
|
|
// Path: "/",
|
|
// Method: hws.MethodGET,
|
|
// Handler: http.HandlerFunc(homeHandler),
|
|
// },
|
|
// }
|
|
//
|
|
// server.AddRoutes(routes...)
|
|
// server.AddMiddleware()
|
|
//
|
|
// ctx := context.Background()
|
|
// server.Start(ctx)
|
|
//
|
|
// <-server.Ready()
|
|
//
|
|
// # Configuration
|
|
//
|
|
// HWS can be configured via environment variables using ConfigFromEnv:
|
|
//
|
|
// HWS_HOST=127.0.0.1 # Host to listen on (default: 127.0.0.1)
|
|
// HWS_PORT=3000 # Port to listen on (default: 3000)
|
|
// HWS_GZIP=false # Enable GZIP compression (default: false)
|
|
// HWS_READ_HEADER_TIMEOUT=2 # Header read timeout in seconds (default: 2)
|
|
// HWS_WRITE_TIMEOUT=10 # Write timeout in seconds (default: 10)
|
|
// HWS_IDLE_TIMEOUT=120 # Idle connection timeout in seconds (default: 120)
|
|
//
|
|
// Or programmatically:
|
|
//
|
|
// cfg := &hws.Config{
|
|
// Host: "0.0.0.0",
|
|
// Port: 8080,
|
|
// GZIP: true,
|
|
// ReadHeaderTimeout: 5 * time.Second,
|
|
// WriteTimeout: 15 * time.Second,
|
|
// IdleTimeout: 120 * time.Second,
|
|
// }
|
|
//
|
|
// # Routing
|
|
//
|
|
// HWS uses Go 1.22+ routing patterns with method-specific handlers:
|
|
//
|
|
// routes := []hws.Route{
|
|
// {
|
|
// Path: "/users/{id}",
|
|
// Method: hws.MethodGET,
|
|
// Handler: http.HandlerFunc(getUser),
|
|
// },
|
|
// {
|
|
// Path: "/users/{id}",
|
|
// Method: hws.MethodPUT,
|
|
// Handler: http.HandlerFunc(updateUser),
|
|
// },
|
|
// }
|
|
//
|
|
// A single route can handle multiple HTTP methods using the Methods field:
|
|
//
|
|
// routes := []hws.Route{
|
|
// {
|
|
// Path: "/api/resource",
|
|
// Methods: []hws.Method{hws.MethodGET, hws.MethodPOST, hws.MethodPUT},
|
|
// Handler: http.HandlerFunc(resourceHandler),
|
|
// },
|
|
// }
|
|
//
|
|
// Note: The Methods field takes precedence over Method if both are provided.
|
|
//
|
|
// Path parameters can be accessed using r.PathValue():
|
|
//
|
|
// func getUser(w http.ResponseWriter, r *http.Request) {
|
|
// id := r.PathValue("id")
|
|
// // ... handle request
|
|
// }
|
|
//
|
|
// # Middleware
|
|
//
|
|
// HWS supports middleware with predictable execution order. Built-in middleware includes
|
|
// request logging, timing, and GZIP compression:
|
|
//
|
|
// server.AddMiddleware()
|
|
//
|
|
// Custom middleware can be added using standard http.Handler wrapping:
|
|
//
|
|
// server.AddMiddleware(customMiddleware)
|
|
//
|
|
// # Error Handling
|
|
//
|
|
// HWS provides structured error handling with customizable error pages:
|
|
//
|
|
// errorPageFunc := func(w http.ResponseWriter, r *http.Request, status int) {
|
|
// w.WriteHeader(status)
|
|
// fmt.Fprintf(w, "Error: %d", status)
|
|
// }
|
|
//
|
|
// server.AddErrorPage(errorPageFunc)
|
|
//
|
|
// # Logging
|
|
//
|
|
// HWS integrates with hlog for structured logging:
|
|
//
|
|
// logger, _ := hlog.NewLogger(loggerCfg, os.Stdout)
|
|
// server.AddLogger(logger)
|
|
//
|
|
// The server will automatically log requests, errors, and server lifecycle events.
|
|
//
|
|
// # Static Files
|
|
//
|
|
// HWS provides safe static file serving that prevents directory listing:
|
|
//
|
|
// server.AddStaticFiles("/static", "./public")
|
|
//
|
|
// # Graceful Shutdown
|
|
//
|
|
// HWS supports graceful shutdown via context cancellation:
|
|
//
|
|
// ctx, cancel := context.WithCancel(context.Background())
|
|
// defer cancel()
|
|
//
|
|
// server.Start(ctx)
|
|
//
|
|
// // Wait for shutdown signal
|
|
// sigChan := make(chan os.Signal, 1)
|
|
// signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
|
// <-sigChan
|
|
//
|
|
// // Cancel context to trigger graceful shutdown
|
|
// cancel()
|
|
//
|
|
// # Integration
|
|
//
|
|
// HWS integrates with:
|
|
// - git.haelnorr.com/h/golib/hlog: For structured logging with zerolog
|
|
// - git.haelnorr.com/h/golib/hwsauth: For JWT-based authentication
|
|
// - git.haelnorr.com/h/golib/jwt: For JWT token management
|
|
package hws
|