Documentation
¶
Index ¶
- func ConvertPatternToMuxFormat(pattern string) string
- func ExtractPathParamValues(pattern, actualPath string) map[string]string
- func ExtractRouteParamNames(path string) []string
- func GetStatusCode(err error) int
- func IsHTTPError(err error) bool
- func LivenessHTTPHandler() http.HandlerFunc
- func ReadinessHTTPHandler(hm *HealthManager) http.HandlerFunc
- func SendError(ctx *Context, statusCode int, message string) error
- func SendHTTPError(ctx *Context, err HTTPError) error
- func SendJSON(ctx *Context, statusCode int, data interface{}) error
- func SetTrustedProxies(proxies []string)
- func WriteError(w http.ResponseWriter, err error)
- func WriteErrorResponse(w http.ResponseWriter, err HTTPError)
- type AuthRateLimitConfig
- type BadRequestError
- type BaseError
- type CheckResult
- type ConflictError
- type Context
- type DatabaseHealthChecker
- type ErrorResponse
- type ForbiddenError
- type HTTPError
- type HTTPHealthChecker
- type HTTPMethod
- type Handler
- type HealthCheckFunc
- type HealthChecker
- type HealthManager
- type HealthManagerOption
- type HealthResponse
- type HealthStatus
- type InternalError
- type Interpreter
- type Middleware
- func AuthMiddleware(validateFunc func(*Context) (bool, error)) Middleware
- func BasicAuthMiddleware(validTokens map[string]bool) Middleware
- func BasicAuthMiddlewareWithConfig(validTokens map[string]bool, config AuthRateLimitConfig) Middleware
- func CORSMiddleware(allowedOrigins []string) Middleware
- func CSRFMiddleware() Middleware
- func ChainMiddlewares(middlewares ...Middleware) Middleware
- func HeaderMiddleware(headers map[string]string) Middleware
- func LoggingMiddleware() Middleware
- func RateLimitMiddleware(config RateLimiterConfig) Middleware
- func RecoveryMiddleware() Middleware
- func SecurityHeadersMiddleware() Middleware
- func TimeoutMiddleware(timeout time.Duration) Middleware
- func TracingMiddleware(config interface{}) Middleware
- type NotFoundError
- type RateLimiterConfig
- type Route
- type RouteHandler
- type RouteNode
- type Router
- type Server
- func (s *Server) GetHandler() *Handler
- func (s *Server) GetRouter() *Router
- func (s *Server) GetWebSocketServer() *ws.Server
- func (s *Server) RegisterHealthRoutes(hm *HealthManager) error
- func (s *Server) RegisterRoute(route *Route) error
- func (s *Server) RegisterRoutes(routes []*Route) error
- func (s *Server) RegisterWebSocketRoute(path string, handler http.HandlerFunc) error
- func (s *Server) Start(addr string) error
- func (s *Server) Stop(ctx context.Context) error
- type ServerOption
- type StaticHealthChecker
- type UnauthorizedError
- type ValidationError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConvertPatternToMuxFormat ¶ added in v0.3.5
ConvertPatternToMuxFormat converts Glyph's :param syntax to Go's {param} syntax for http.ServeMux pattern matching. e.g., "/chat/:room" becomes "/chat/{room}"
func ExtractPathParamValues ¶ added in v0.3.5
ExtractPathParamValues extracts parameter values from an actual path given a pattern. pattern: "/chat/:room" actualPath: "/chat/general" -> {"room": "general"} Handles URL-encoded values by decoding them.
func ExtractRouteParamNames ¶ added in v0.3.5
ExtractRouteParamNames extracts parameter names from a route pattern. e.g., "/users/:id/:action" returns ["id", "action"] e.g., "/chat/:room" returns ["room"]
func GetStatusCode ¶
GetStatusCode extracts the status code from an error Returns 500 if not an HTTPError
func IsHTTPError ¶
IsHTTPError checks if an error implements HTTPError interface
func LivenessHTTPHandler ¶
func LivenessHTTPHandler() http.HandlerFunc
LivenessHTTPHandler creates a standard http.Handler for liveness checks
func ReadinessHTTPHandler ¶
func ReadinessHTTPHandler(hm *HealthManager) http.HandlerFunc
ReadinessHTTPHandler creates a standard http.Handler for readiness checks
func SendHTTPError ¶
SendHTTPError is a helper to send HTTPError responses in handlers
func SetTrustedProxies ¶ added in v0.5.0
func SetTrustedProxies(proxies []string)
SetTrustedProxies configures the set of trusted proxy IP addresses. Only requests from these addresses will have their X-Forwarded-For and X-Real-IP headers honored for client IP extraction. This function is safe for concurrent use.
func WriteError ¶
func WriteError(w http.ResponseWriter, err error)
WriteError writes a generic error as JSON response If err implements HTTPError, uses that. Otherwise creates InternalError.
func WriteErrorResponse ¶
func WriteErrorResponse(w http.ResponseWriter, err HTTPError)
WriteErrorResponse writes an HTTPError as JSON response
Types ¶
type AuthRateLimitConfig ¶
type AuthRateLimitConfig struct {
MaxFailures int // Maximum failures before lockout (default: 5)
LockoutDuration time.Duration // Initial lockout duration (default: 1 minute)
MaxLockout time.Duration // Maximum lockout duration with exponential backoff (default: 15 minutes)
ResetAfter time.Duration // Reset failure count after this duration of no failures (default: 15 minutes)
TrustProxy bool // When true, use X-Forwarded-For/X-Real-IP headers for client IP
}
AuthRateLimitConfig configures auth rate limiting behavior
func DefaultAuthRateLimitConfig ¶
func DefaultAuthRateLimitConfig() AuthRateLimitConfig
DefaultAuthRateLimitConfig returns sensible defaults for auth rate limiting
type BadRequestError ¶
type BadRequestError struct {
*BaseError
}
BadRequestError represents a 400 Bad Request error (generic)
func NewBadRequestError ¶
func NewBadRequestError(message string) *BadRequestError
NewBadRequestError creates a new bad request error
func NewBadRequestErrorWithCause ¶
func NewBadRequestErrorWithCause(message string, cause error) *BadRequestError
NewBadRequestErrorWithCause creates a bad request error with cause
type BaseError ¶
BaseError provides common functionality for all error types
func (*BaseError) StatusCode ¶
func (*BaseError) ToResponse ¶
func (e *BaseError) ToResponse() *ErrorResponse
type CheckResult ¶
type CheckResult struct {
Status HealthStatus `json:"status"`
LatencyMs int64 `json:"latency_ms,omitempty"`
Message string `json:"message,omitempty"`
Error string `json:"error,omitempty"`
}
CheckResult represents the result of a single health check
type ConflictError ¶
ConflictError represents a 409 Conflict error
func NewConflictError ¶
func NewConflictError(resource, message string) *ConflictError
NewConflictError creates a new conflict error
type Context ¶
type Context struct {
Request *http.Request
ResponseWriter http.ResponseWriter
PathParams map[string]string
QueryParams map[string][]string // All values for each query param
Body map[string]interface{}
StatusCode int
}
Context represents the request context with parsed parameters
type DatabaseHealthChecker ¶
type DatabaseHealthChecker struct {
// contains filtered or unexported fields
}
DatabaseHealthChecker checks database connectivity
func NewDatabaseHealthChecker ¶
func NewDatabaseHealthChecker(name string, pingFn func(ctx context.Context) error) *DatabaseHealthChecker
NewDatabaseHealthChecker creates a new database health checker
func (*DatabaseHealthChecker) Check ¶
func (d *DatabaseHealthChecker) Check(ctx context.Context) *CheckResult
Check performs the database health check
func (*DatabaseHealthChecker) Name ¶
func (d *DatabaseHealthChecker) Name() string
Name returns the checker name
type ErrorResponse ¶
type ErrorResponse struct {
Status int `json:"status"`
Error string `json:"error"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}
ErrorResponse represents a standardized JSON error response
type ForbiddenError ¶
ForbiddenError represents a 403 Forbidden error
func NewForbiddenError ¶
func NewForbiddenError(action string) *ForbiddenError
NewForbiddenError creates a new forbidden error
type HTTPError ¶
type HTTPError interface {
error
StatusCode() int
ErrorType() string
ToResponse() *ErrorResponse
}
HTTPError is the base interface for all HTTP errors
type HTTPHealthChecker ¶
type HTTPHealthChecker struct {
// contains filtered or unexported fields
}
HTTPHealthChecker checks external HTTP service availability
func NewHTTPHealthChecker ¶
func NewHTTPHealthChecker(name, urlStr string) (*HTTPHealthChecker, error)
NewHTTPHealthChecker creates a new HTTP service health checker. The URL must use http or https scheme. Returns an error if the URL is invalid or points to a private/loopback network address.
func (*HTTPHealthChecker) Check ¶
func (h *HTTPHealthChecker) Check(ctx context.Context) *CheckResult
Check performs the HTTP health check
func (*HTTPHealthChecker) Name ¶
func (h *HTTPHealthChecker) Name() string
Name returns the checker name
type HTTPMethod ¶
type HTTPMethod string
HTTPMethod represents an HTTP method
const ( GET HTTPMethod = "GET" POST HTTPMethod = "POST" PUT HTTPMethod = "PUT" DELETE HTTPMethod = "DELETE" PATCH HTTPMethod = "PATCH" )
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler creates an HTTP handler function for routing
func NewHandler ¶
func NewHandler(router *Router, interpreter Interpreter) *Handler
NewHandler creates a new handler with the given router and interpreter
type HealthCheckFunc ¶
type HealthCheckFunc struct {
// contains filtered or unexported fields
}
HealthCheckFunc is a function type that implements HealthChecker
func NewHealthCheckFunc ¶
func NewHealthCheckFunc(name string, fn func(ctx context.Context) *CheckResult) *HealthCheckFunc
NewHealthCheckFunc creates a new HealthCheckFunc
func (*HealthCheckFunc) Check ¶
func (f *HealthCheckFunc) Check(ctx context.Context) *CheckResult
Check implements HealthChecker
func (*HealthCheckFunc) Name ¶
func (f *HealthCheckFunc) Name() string
Name implements HealthChecker
type HealthChecker ¶
type HealthChecker interface {
// Check performs a health check and returns the result
// The context may contain a timeout
Check(ctx context.Context) *CheckResult
// Name returns the name of this health checker
Name() string
}
HealthChecker is an interface for components that can report their health
type HealthManager ¶
type HealthManager struct {
// contains filtered or unexported fields
}
HealthManager manages health checks and provides endpoints
Example ¶
ExampleHealthManager demonstrates basic health check setup
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a health manager
hm := server.NewHealthManager(
server.WithHealthCheckTimeout(5 * time.Second),
)
// Register a custom health checker
hm.RegisterChecker(server.NewHealthCheckFunc("my-service", func(ctx context.Context) *server.CheckResult {
// Perform your health check logic here
return &server.CheckResult{
Status: server.StatusHealthy,
LatencyMs: 5,
}
}))
// Create server and register health routes
srv := server.NewServer()
if err := srv.RegisterHealthRoutes(hm); err != nil {
log.Fatal(err)
}
fmt.Println("Health routes registered: /health/live, /health/ready, /health")
}
Output: Health routes registered: /health/live, /health/ready, /health
Example (CustomChecker) ¶
ExampleHealthManager_customChecker demonstrates creating a custom health checker
package main
import (
"context"
"fmt"
"time"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a health manager
hm := server.NewHealthManager()
// Create a custom health checker with specific logic
customChecker := server.NewHealthCheckFunc("redis", func(ctx context.Context) *server.CheckResult {
start := time.Now()
// Perform your custom health check logic
// For example, check Redis connection
// err := redisClient.Ping(ctx).Err()
latency := time.Since(start).Milliseconds()
// Simulate a healthy check
return &server.CheckResult{
Status: server.StatusHealthy,
LatencyMs: latency,
Message: "Redis is operational",
}
})
hm.RegisterChecker(customChecker)
fmt.Println("Custom Redis health checker registered")
}
Output: Custom Redis health checker registered
Example (DatabaseChecker) ¶
ExampleHealthManager_databaseChecker demonstrates database health checking
package main
import (
"context"
"database/sql"
"fmt"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a health manager
hm := server.NewHealthManager()
// Simulate a database connection (in real code, use your actual DB)
var db *sql.DB // This would be your actual database connection
// Register a database health checker
dbChecker := server.NewDatabaseHealthChecker("database", func(ctx context.Context) error {
// In real code, use db.PingContext(ctx)
if db == nil {
return nil // For this example
}
return db.PingContext(ctx)
})
hm.RegisterChecker(dbChecker)
fmt.Println("Database health checker registered")
}
Output: Database health checker registered
Example (DegradedStatus) ¶
ExampleHealthManager_degradedStatus demonstrates handling degraded service status
package main
import (
"context"
"fmt"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a custom checker that returns degraded status
checker := server.NewHealthCheckFunc("slow-service", func(ctx context.Context) *server.CheckResult {
// Simulate a slow but functional service
return &server.CheckResult{
Status: server.StatusDegraded,
LatencyMs: 250,
Message: "Service is slow but operational",
}
})
fmt.Println(checker.Name())
result := checker.Check(context.Background())
fmt.Println(result.Status)
}
Output: slow-service degraded
Example (HttpChecker) ¶
ExampleHealthManager_httpChecker demonstrates external service health checking
package main
import (
"fmt"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a health manager
hm := server.NewHealthManager()
// Register an HTTP service health checker
apiChecker, err := server.NewHTTPHealthChecker("external-api", "https://api.example.com/health")
if err != nil {
fmt.Println("Error:", err)
return
}
hm.RegisterChecker(apiChecker)
fmt.Println("External API health checker registered")
}
Output: External API health checker registered
Example (MultipleCheckers) ¶
ExampleHealthManager_multipleCheckers demonstrates using multiple health checkers
package main
import (
"fmt"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a health manager
hm := server.NewHealthManager()
// Register multiple checkers
hm.RegisterChecker(server.NewStaticHealthChecker("database", server.StatusHealthy))
hm.RegisterChecker(server.NewStaticHealthChecker("redis", server.StatusHealthy))
hm.RegisterChecker(server.NewStaticHealthChecker("elasticsearch", server.StatusHealthy))
fmt.Println("3 health checkers registered")
}
Output: 3 health checkers registered
Example (StandaloneHTTP) ¶
ExampleHealthManager_standaloneHTTP demonstrates using health handlers without the GLYPHLANG server
package main
import (
"fmt"
"net/http"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a health manager
hm := server.NewHealthManager()
// Register some checkers
hm.RegisterChecker(server.NewStaticHealthChecker("db", server.StatusHealthy))
// Use with standard http.ServeMux
mux := http.NewServeMux()
mux.HandleFunc("/health/live", server.LivenessHTTPHandler())
mux.HandleFunc("/health/ready", server.ReadinessHTTPHandler(hm))
fmt.Println("Health endpoints registered with http.ServeMux")
}
Output: Health endpoints registered with http.ServeMux
Example (Timeout) ¶
ExampleHealthManager_timeout demonstrates health check with timeout
package main
import (
"context"
"fmt"
"time"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create a health manager with short timeout
hm := server.NewHealthManager(
server.WithHealthCheckTimeout(100 * time.Millisecond),
)
// Register a checker that respects context timeout
hm.RegisterChecker(server.NewHealthCheckFunc("service", func(ctx context.Context) *server.CheckResult {
select {
case <-ctx.Done():
return &server.CheckResult{
Status: server.StatusUnhealthy,
Error: "timeout exceeded",
}
case <-time.After(50 * time.Millisecond):
return &server.CheckResult{
Status: server.StatusHealthy,
}
}
}))
fmt.Println("Health manager configured with 100ms timeout")
}
Output: Health manager configured with 100ms timeout
func NewHealthManager ¶
func NewHealthManager(options ...HealthManagerOption) *HealthManager
NewHealthManager creates a new health manager
func (*HealthManager) HealthHandler ¶
func (hm *HealthManager) HealthHandler() RouteHandler
HealthHandler handles detailed health check requests Similar to readiness but always returns 200 with detailed status
func (*HealthManager) LivenessHandler ¶
func (hm *HealthManager) LivenessHandler() RouteHandler
LivenessHandler handles liveness probe requests Liveness probes check if the application is running Returns 200 if the application is alive
func (*HealthManager) ReadinessHandler ¶
func (hm *HealthManager) ReadinessHandler() RouteHandler
ReadinessHandler handles readiness probe requests Readiness probes check if the application is ready to serve traffic Returns 200 if ready, 503 if not ready
func (*HealthManager) RegisterChecker ¶
func (hm *HealthManager) RegisterChecker(checker HealthChecker)
RegisterChecker registers a new health checker
func (*HealthManager) UnregisterChecker ¶
func (hm *HealthManager) UnregisterChecker(name string)
UnregisterChecker removes a health checker
type HealthManagerOption ¶
type HealthManagerOption func(*HealthManager)
HealthManagerOption is a functional option for configuring the health manager
func WithHealthCheckTimeout ¶
func WithHealthCheckTimeout(timeout time.Duration) HealthManagerOption
WithHealthCheckTimeout sets the timeout for health checks
type HealthResponse ¶
type HealthResponse struct {
Status HealthStatus `json:"status"`
Checks map[string]*CheckResult `json:"checks,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
HealthResponse represents the aggregated health check response
type HealthStatus ¶
type HealthStatus string
HealthStatus represents the health status of a component
const ( // StatusHealthy indicates the component is functioning properly StatusHealthy HealthStatus = "healthy" // StatusDegraded indicates the component is functioning but with issues StatusDegraded HealthStatus = "degraded" // StatusUnhealthy indicates the component is not functioning StatusUnhealthy HealthStatus = "unhealthy" )
type InternalError ¶
type InternalError struct {
*BaseError
}
InternalError represents a 500 Internal Server Error
func NewInternalError ¶
func NewInternalError(message string) *InternalError
NewInternalError creates a new internal server error
func NewInternalErrorWithCause ¶
func NewInternalErrorWithCause(message string, cause error) *InternalError
NewInternalErrorWithCause creates an internal error with a cause
type Interpreter ¶
Interpreter interface for executing GLYPH route logic This will be properly implemented later - for now we mock it
type Middleware ¶
type Middleware func(next RouteHandler) RouteHandler
Middleware is a function that wraps a handler
func AuthMiddleware ¶
func AuthMiddleware(validateFunc func(*Context) (bool, error)) Middleware
AuthMiddleware is a placeholder for authentication middleware In production, this would validate JWT tokens, API keys, or session tokens
func BasicAuthMiddleware ¶
func BasicAuthMiddleware(validTokens map[string]bool) Middleware
BasicAuthMiddleware provides simple token-based authentication with rate limiting to prevent brute force attacks
func BasicAuthMiddlewareWithConfig ¶
func BasicAuthMiddlewareWithConfig(validTokens map[string]bool, config AuthRateLimitConfig) Middleware
BasicAuthMiddlewareWithConfig provides token-based authentication with custom rate limit config
func CORSMiddleware ¶
func CORSMiddleware(allowedOrigins []string) Middleware
CORSMiddleware adds CORS headers to responses Security: When allowedOrigins contains "*", we set the literal "*" header and explicitly disable credentials to prevent security vulnerabilities
func CSRFMiddleware ¶ added in v0.5.0
func CSRFMiddleware() Middleware
CSRFMiddleware provides Cross-Site Request Forgery protection. It generates a random token and sets it as a cookie. On state-changing requests (POST, PUT, PATCH, DELETE), it validates the token from either the X-CSRF-Token header or the csrf_token form field. This middleware is opt-in.
func ChainMiddlewares ¶
func ChainMiddlewares(middlewares ...Middleware) Middleware
ChainMiddlewares combines multiple middlewares into one
func HeaderMiddleware ¶
func HeaderMiddleware(headers map[string]string) Middleware
HeaderMiddleware adds custom headers to all responses
func RateLimitMiddleware ¶
func RateLimitMiddleware(config RateLimiterConfig) Middleware
RateLimitMiddleware implements simple in-memory rate limiting
func RecoveryMiddleware ¶
func RecoveryMiddleware() Middleware
RecoveryMiddleware recovers from panics and returns 500 error It logs full panic details to server logs but returns a generic error to clients to prevent information disclosure
func SecurityHeadersMiddleware ¶
func SecurityHeadersMiddleware() Middleware
SecurityHeadersMiddleware adds security headers to all responses These headers help protect against common web vulnerabilities
func TimeoutMiddleware ¶
func TimeoutMiddleware(timeout time.Duration) Middleware
TimeoutMiddleware adds a timeout to request processing
func TracingMiddleware ¶
func TracingMiddleware(config interface{}) Middleware
TracingMiddleware creates a middleware that adds OpenTelemetry distributed tracing This middleware integrates with the pkg/tracing package It should be added early in the middleware chain to trace the entire request lifecycle
Usage:
import "github.com/glyphlang/glyph/pkg/tracing"
config := tracing.DefaultMiddlewareConfig()
server := NewServer(
WithMiddleware(TracingMiddleware(config)),
)
Note: This requires the tracing package to be initialized first:
tp, err := tracing.InitTracing(tracing.DefaultConfig()) defer tp.Shutdown(context.Background())
type NotFoundError ¶
NotFoundError represents a 404 Not Found error
func NewNotFoundError ¶
func NewNotFoundError(resource string) *NotFoundError
NewNotFoundError creates a new not found error
func NewNotFoundErrorWithDetails ¶
func NewNotFoundErrorWithDetails(resource, message string) *NotFoundError
NewNotFoundErrorWithDetails creates a not found error with custom message
type RateLimiterConfig ¶
type RateLimiterConfig struct {
RequestsPerMinute int
BurstSize int
TrustProxy bool // When true, use X-Forwarded-For/X-Real-IP headers for client IP
}
RateLimitMiddleware is a placeholder for rate limiting middleware In production, this would use a proper rate limiter (e.g., token bucket, Redis)
type Route ¶
type Route struct {
Method HTTPMethod
Path string
Handler RouteHandler
Middlewares []Middleware
}
Route represents a parsed GLYPH route definition
type RouteHandler ¶
RouteHandler is a function that handles a matched route
type RouteNode ¶
type RouteNode struct {
// contains filtered or unexported fields
}
RouteNode represents a node in the route tree
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router manages route registration and matching
func (*Router) GetAllRoutes ¶
func (r *Router) GetAllRoutes() map[HTTPMethod][]*Route
GetAllRoutes returns all registered routes
func (*Router) GetRoutes ¶
func (r *Router) GetRoutes(method HTTPMethod) []*Route
GetRoutes returns all registered routes for a method
func (*Router) RegisterRoute ¶
RegisterRoute adds a route to the router
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server represents the HTTP server
Example ¶
ExampleServer demonstrates basic server usage
package main
import (
"fmt"
"net/http/httptest"
"github.com/glyphlang/glyph/pkg/server"
)
// exampleMockInterpreter implements server.Interpreter for examples
type exampleMockInterpreter struct {
Response interface{}
}
func (m *exampleMockInterpreter) Execute(route *server.Route, ctx *server.Context) (interface{}, error) {
if m.Response != nil {
return m.Response, nil
}
query := make(map[string]interface{})
for k, v := range ctx.QueryParams {
if len(v) == 1 {
query[k] = v[0]
} else {
query[k] = v
}
}
response := map[string]interface{}{
"message": "Mock response",
"path": ctx.Request.URL.Path,
"method": ctx.Request.Method,
"pathParams": ctx.PathParams,
"query": query,
}
if ctx.Body != nil && len(ctx.Body) > 0 {
response["body"] = ctx.Body
}
return response, nil
}
func main() {
// Create a new server with mock interpreter
srv := server.NewServer(
server.WithInterpreter(&exampleMockInterpreter{
Response: map[string]interface{}{
"message": "Hello, World!",
},
}),
)
// Register a simple route
srv.RegisterRoute(&server.Route{
Method: server.GET,
Path: "/hello",
})
// Make a test request
req := httptest.NewRequest("GET", "/hello", nil)
w := httptest.NewRecorder()
srv.GetHandler().ServeHTTP(w, req)
fmt.Println(w.Code)
}
Output: 200
Example (CustomHandler) ¶
ExampleServer_customHandler demonstrates custom request handlers
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http/httptest"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
srv := server.NewServer()
// Register route with custom handler
srv.RegisterRoute(&server.Route{
Method: server.POST,
Path: "/api/users",
Handler: func(ctx *server.Context) error {
// Access request body
name := ctx.Body["name"].(string)
// Send custom response
return server.SendJSON(ctx, 201, map[string]interface{}{
"message": fmt.Sprintf("User %s created", name),
"id": "new-id-123",
})
},
})
// Make request
body, _ := json.Marshal(map[string]string{"name": "John"})
req := httptest.NewRequest("POST", "/api/users", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
srv.GetHandler().ServeHTTP(w, req)
fmt.Println(w.Code)
}
Output: 201
Example (Middleware) ¶
ExampleServer_middleware demonstrates middleware usage
package main
import (
"fmt"
"net/http/httptest"
"github.com/glyphlang/glyph/pkg/server"
)
func main() {
// Create middleware that adds a header
headerMiddleware := func(next server.RouteHandler) server.RouteHandler {
return func(ctx *server.Context) error {
ctx.ResponseWriter.Header().Set("X-Custom", "value")
return next(ctx)
}
}
srv := server.NewServer()
// Register route with middleware
srv.RegisterRoute(&server.Route{
Method: server.GET,
Path: "/test",
Middlewares: []server.Middleware{headerMiddleware},
Handler: func(ctx *server.Context) error {
return server.SendJSON(ctx, 200, map[string]string{"status": "ok"})
},
})
req := httptest.NewRequest("GET", "/test", nil)
w := httptest.NewRecorder()
srv.GetHandler().ServeHTTP(w, req)
fmt.Println(w.Header().Get("X-Custom"))
}
Output: value
Example (PathParams) ¶
ExampleServer_pathParams demonstrates path parameter extraction
package main
import (
"encoding/json"
"fmt"
"net/http/httptest"
"github.com/glyphlang/glyph/pkg/server"
)
// exampleMockInterpreter implements server.Interpreter for examples
type exampleMockInterpreter struct {
Response interface{}
}
func (m *exampleMockInterpreter) Execute(route *server.Route, ctx *server.Context) (interface{}, error) {
if m.Response != nil {
return m.Response, nil
}
query := make(map[string]interface{})
for k, v := range ctx.QueryParams {
if len(v) == 1 {
query[k] = v[0]
} else {
query[k] = v
}
}
response := map[string]interface{}{
"message": "Mock response",
"path": ctx.Request.URL.Path,
"method": ctx.Request.Method,
"pathParams": ctx.PathParams,
"query": query,
}
if ctx.Body != nil && len(ctx.Body) > 0 {
response["body"] = ctx.Body
}
return response, nil
}
func main() {
srv := server.NewServer(
server.WithInterpreter(&exampleMockInterpreter{}),
)
// Register route with path parameters
srv.RegisterRoute(&server.Route{
Method: server.GET,
Path: "/users/:id",
})
// Make request
req := httptest.NewRequest("GET", "/users/123", nil)
w := httptest.NewRecorder()
srv.GetHandler().ServeHTTP(w, req)
var response map[string]interface{}
json.Unmarshal(w.Body.Bytes(), &response)
pathParams := response["pathParams"].(map[string]interface{})
fmt.Println(pathParams["id"])
}
Output: 123
func NewServer ¶
func NewServer(options ...ServerOption) *Server
NewServer creates a new HTTP server instance
func (*Server) GetHandler ¶
GetHandler returns the server's handler
func (*Server) GetWebSocketServer ¶
GetWebSocketServer returns the WebSocket server
func (*Server) RegisterHealthRoutes ¶
func (s *Server) RegisterHealthRoutes(hm *HealthManager) error
RegisterHealthRoutes registers all health check routes with the server
func (*Server) RegisterRoute ¶
RegisterRoute registers a single route
func (*Server) RegisterRoutes ¶
RegisterRoutes registers multiple routes
func (*Server) RegisterWebSocketRoute ¶
func (s *Server) RegisterWebSocketRoute(path string, handler http.HandlerFunc) error
RegisterWebSocketRoute registers a WebSocket route
type ServerOption ¶
type ServerOption func(*Server)
ServerOption is a functional option for configuring the server
func WithInterpreter ¶
func WithInterpreter(interpreter Interpreter) ServerOption
WithInterpreter sets the interpreter for the server
func WithMiddleware ¶
func WithMiddleware(middleware Middleware) ServerOption
WithMiddleware adds a global middleware to the server
type StaticHealthChecker ¶
type StaticHealthChecker struct {
// contains filtered or unexported fields
}
StaticHealthChecker always returns a fixed status (useful for testing)
func NewStaticHealthChecker ¶
func NewStaticHealthChecker(name string, status HealthStatus) *StaticHealthChecker
NewStaticHealthChecker creates a health checker that always returns the same status
func (*StaticHealthChecker) Check ¶
func (s *StaticHealthChecker) Check(ctx context.Context) *CheckResult
Check returns the static status
func (*StaticHealthChecker) Name ¶
func (s *StaticHealthChecker) Name() string
Name returns the checker name
type UnauthorizedError ¶
type UnauthorizedError struct {
}
UnauthorizedError represents a 401 Unauthorized error
func NewUnauthorizedError ¶
func NewUnauthorizedError(reason string) *UnauthorizedError
NewUnauthorizedError creates a new unauthorized error
func NewUnauthorizedErrorWithMessage ¶
func NewUnauthorizedErrorWithMessage(message, reason string) *UnauthorizedError
NewUnauthorizedErrorWithMessage creates an unauthorized error with custom message
func (*UnauthorizedError) ToResponse ¶
func (e *UnauthorizedError) ToResponse() *ErrorResponse
ToResponse overrides to include reason in details
type ValidationError ¶
ValidationError represents a 400 Bad Request error
func NewValidationError ¶
func NewValidationError(field, message string) *ValidationError
NewValidationError creates a new validation error
func NewValidationErrorWithDetails ¶
func NewValidationErrorWithDetails(field, message, details string) *ValidationError
NewValidationErrorWithDetails creates a validation error with additional details
func (*ValidationError) ToResponse ¶
func (e *ValidationError) ToResponse() *ErrorResponse
ToResponse overrides the base method to include field information