Documentation Index
Fetch the complete documentation index at: https://mintlify.com/platforma-dev/platforma/llms.txt
Use this file to discover all available pages before exploring further.
The httpserver package provides an HTTP server with middleware support, handler groups, and graceful shutdown capabilities.
HTTPServer Type
The HTTPServer type represents an HTTP server with middleware support and graceful shutdown.
type HTTPServer struct {
// Embeds HandlerGroup for routing capabilities
port string
shutdownTimeout time.Duration
}
Constructor
New(port, shutdownTimeout)
Creates a new HTTPServer instance.Parameters:
port (string): The port number to listen on (e.g., “8080”)
shutdownTimeout (time.Duration): Maximum time to wait for graceful shutdown
server := httpserver.New("8080", 3*time.Second)
HTTPServer Methods
Run
Starts the HTTP server and handles graceful shutdown when the context is canceled.The server will:
- Start listening on the configured port
- Block until the context is canceled (e.g., interrupt signal)
- Gracefully shut down within the shutdown timeout
if err := server.Run(ctx); err != nil {
log.ErrorContext(ctx, "server error", "error", err)
}
Healthcheck
Healthcheck(ctx context.Context)
Returns health check information for the HTTP server.health := server.Healthcheck(ctx)
// Returns: map[string]any{"port": "8080"}
HandlerGroup Type
The HandlerGroup represents a group of HTTP handlers that share common middleware.
type HandlerGroup struct {
mux *http.ServeMux
middlewares []Middleware
}
Constructor
Creates a new HandlerGroup with an initialized http.ServeMux.group := httpserver.NewHandlerGroup()
HandlerGroup Methods
Handle
Handle(pattern string, handler http.Handler)
Registers an http.Handler for the given pattern.server.Handle("/api", myHandler)
HandleFunc
HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
Registers an http.HandlerFunc for the given pattern.server.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("pong"))
})
HandleGroup
HandleGroup(pattern string, handler http.Handler)
Applies http.StripPrefix to the handler and registers it for the given pattern. Useful for mounting sub-routers.subGroup := httpserver.NewHandlerGroup()
subGroup.HandleFunc("/users", listUsers)
server.HandleGroup("/api", subGroup)
// Accessible at: /api/users
Use
Use(middlewares ...Middleware)
Adds one or more middlewares to the HandlerGroup’s middleware chain.server.Use(log.NewTraceIDMiddleware(nil, ""))
UseFunc
UseFunc(middlewareFuncs ...func(http.Handler) http.Handler)
Adds functions as middleware to the HandlerGroup’s middleware chain.server.UseFunc(func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.InfoContext(r.Context(), "request", "path", r.URL.Path)
h.ServeHTTP(w, r)
})
})
ServeHTTP
ServeHTTP(w http.ResponseWriter, r *http.Request)
Implements the http.Handler interface, allowing HandlerGroup to be used as an HTTP handler itself.
Middleware Interface
The Middleware interface defines HTTP middleware.
type Middleware interface {
Wrap(http.Handler) http.Handler
}
Wrap
func(http.Handler) http.Handler
Wraps an http.Handler with middleware logic.
MiddlewareFunc
A convenience type that implements the Middleware interface.
type MiddlewareFunc func(http.Handler) http.Handler
func (f MiddlewareFunc) Wrap(h http.Handler) http.Handler {
return f(h)
}
Built-in Middleware
RecoverMiddleware
The RecoverMiddleware catches panics in HTTP handlers and returns an HTTP 500 response.
type RecoverMiddleware struct{}
Creates a new RecoverMiddleware instance.server := httpserver.New("8080", 3*time.Second)
server.Use(httpserver.NewRecoverMiddleware())
The middleware will:
- Catch any panic in downstream handlers
- Log the panic with request context
- Return HTTP 500 Internal Server Error response
- Prevent the server from crashing
FileServer Type
The FileServer serves static files from an embedded file system.
type FileServer struct {
server *HTTPServer
}
NewFileServer(fs, basePath, port)
Creates a new FileServer for serving static files.Parameters:
fs (fs.FS): The file system to serve (can be embedded)
basePath (string): The URL path prefix (e.g., “/static”)
port (string): The port to listen on
//go:embed static
var staticFiles embed.FS
fileServer := httpserver.NewFileServer(staticFiles, "/static", "8080")
app.RegisterService("static", fileServer)
Example Usage
Basic HTTP Server
package main
import (
"context"
"net/http"
"time"
"github.com/platforma-dev/platforma/application"
"github.com/platforma-dev/platforma/httpserver"
"github.com/platforma-dev/platforma/log"
)
func main() {
ctx := context.Background()
app := application.New()
// Create HTTP server
api := httpserver.New("8080", 3*time.Second)
// Add endpoints
api.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("pong"))
})
// Add middleware
api.Use(log.NewTraceIDMiddleware(nil, ""))
// Register with application
app.RegisterService("api", api)
if err := app.Run(ctx); err != nil {
log.ErrorContext(ctx, "app failed", "error", err)
}
}
Using Handler Groups
// Create main server
api := httpserver.New("8080", 3*time.Second)
// Create a sub-group for API v1
apiV1 := httpserver.NewHandlerGroup()
apiV1.HandleFunc("/users", listUsers)
apiV1.HandleFunc("/posts", listPosts)
// Add middleware to the group
apiV1.UseFunc(func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.InfoContext(r.Context(), "API v1 request", "path", r.URL.Path)
h.ServeHTTP(w, r)
})
})
// Mount the group
api.HandleGroup("/api/v1", apiV1)
// Accessible at:
// - /api/v1/users
// - /api/v1/posts
Custom Middleware
type LoggingMiddleware struct{}
func (m *LoggingMiddleware) Wrap(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
log.InfoContext(r.Context(), "request started", "method", r.Method, "path", r.URL.Path)
h.ServeHTTP(w, r)
log.InfoContext(r.Context(), "request completed", "duration", time.Since(start))
})
}
server.Use(&LoggingMiddleware{})