Documentation
¶
Overview ¶
Package http (Navigator, Bridge, Tempose, and Glide) houses the core HTTP request-response lifecycle management. It abstracts raw net/http primitives into a high-level developer API.
Package http (Navigator, Bridge, Tempose, and Glide) houses the pipeline, routing, and context tracking systems governing the lifecycle of incoming web and API traffic.
Package http (Navigator, Bridge, Tempose, and Glide) houses the pipeline, routing, and context tracking systems governing the lifecycle of incoming web and API traffic.
Package http (Navigator, Bridge, Tempose, and Glide) houses the core HTTP request-response lifecycle management.
Purpose: This file implements the session lifecycle middleware and clean context helper accessors. It bridges incoming HTTP client cookie requests with our backend SessionStore interfaces.
Philosophy: State resolution must be completely transparent to the application. By integrating session loading as an HTTP middleware layer, controllers get automatic, risk-free access to user session stores on demand, ensuring the developer experience remains fluid and standard-library oriented.
Architecture: Acts as a standard GoStack Middleware. It runs early in the request routing pipeline to: 1. Inspect request cookies. 2. Resolve or generate unique session tokens. 3. Bind session references directly to the request Context values. 4. Set response cookies before handlers flush headers. 5. Save state changes back to the store after the pipeline completes.
Choice: We chose to generate 32-byte cryptographically secure hexadecimal IDs using crypto/rand rather than basic timestamp counters or UUIDs to protect GoStack applications against session hijacking and brute-force guessing attacks out-of-the-box. We commit the cookie prior to running next(ctx) because standard Go response streams lock headers upon the first Write/WriteHeader invocation.
Implementation: - SessionMiddleware: Middleware generator registering the lifecycle hooks. - GetSession: Static helper method to fetch resolved session pointers cleanly from Context. - generateSessionID: Private cryptographic utility to seed new session ID strings.
Purpose: This file implements standard in-memory session structures that fulfill the Session and SessionStore contracts. It handles individual request thread-safe state access and centralized map-based storage.
Philosophy: We prioritize simplicity and execution speed. During local development or single-instance deployments, a fast, locks-guarded memory store keeps execution overhead at zero without requiring external database table setups or Redis infrastructure.
Architecture: Implements framework/contract/session interfaces. The MemorySession manages isolated key-value pairs, while InMemoryStore coordinates the persistent sessions map.
Choice: We chose sync.RWMutex over sync.Map because it allows clean, explicit atomic locking of the entire data block during operations like Clear() or model pointer validation, while supporting multiple readers concurrently without runtime overhead.
Implementation: - MemorySession: Struct representing a single active user session. - InMemoryStore: Struct managing the global active sessions in-memory.
Package http (Navigator, Bridge, Tempose, and Glide) houses the core HTTP request-response lifecycle management. It provides the primitives for routing, context propagation, and view rendering for the GoStack framework.
Purpose: This file provides a lightweight, interface-driven validation layer for incoming HTTP request data, extended with a declarative rule composition engine for expressive, Laravel-style field validation.
Philosophy: We believe request validation should be performant and integrated directly with the routing pipeline. By compiling structural validators into middleware, we filter bad payloads before executing controller logic. Rules should read like a policy document, not imperative if-chains — making validation intent obvious at a glance.
Architecture: Two complementary layers:
- ValidateRequest middleware — decodes the JSON body, invokes the Validator interface, and short- circuits with a 422 response on failure. Unchanged from the original design.
- Rules engine — a reflect-based composer that iterates a RuleSet map, extracts string representations of struct field values, and applies each Rule function in order, collecting all failures into a single error map.
Choice: We chose a function-value approach for Rule (func(field, value string) (bool, string)) over string tags (e.g. `validate:"required|email"`) to preserve compile-time safety, allow closures for parameterised rules (MinLength, MaxLength), and avoid a secondary tag parser.
Implementation: - Validator: interface all request structs must implement to expose their error map. - ValidateRequest: middleware factory that decodes JSON and dispatches to Validate(). - typeCache: thread-safe sync.Map caching reflection types to amortise repeated parsing cost. - Rule: a validation function signature — receives field name + string value, returns ok + message. - RuleSet: a map of struct field names to ordered slices of Rule functions. - Rules(src, set): reflects over src, coerces each field to string, and runs its rules. - Built-in rules: Required, IsEmail, IsNumeric, MinLength(n), MaxLength(n), Matches(pattern).
Index ¶
- Constants
- func GetSession(ctx *Context) contract.Session
- func Logger(ctx *Context, next NextHandler) error
- func RequireAuth(ctx *Context, next NextHandler) error
- func Rules(src any, set RuleSet) map[string]string
- type Connection
- type Context
- func (c *Context) Get(key string) any
- func (c *Context) JSON(code int, data any) error
- func (c *Context) Locale() string
- func (c *Context) Post(key string) string
- func (c *Context) Query(key string) string
- func (c *Context) Render(viewName string, data any) error
- func (c *Context) Set(key string, val any)
- func (c *Context) Trans(key string, replace ...map[string]string) string
- type Engine
- type Hub
- func (h *Hub) Broadcast(msg []byte)
- func (h *Hub) BroadcastToRoom(room string, msg []byte)
- func (h *Hub) Handler() http.Handler
- func (h *Hub) HandlerForUser(userID string) http.Handler
- func (h *Hub) JoinRoom(room string, conn *Connection)
- func (h *Hub) LeaveRoom(room string, conn *Connection)
- func (h *Hub) Run(ctx context.Context)
- func (h *Hub) SendTo(userID string, msg []byte)
- type InMemoryStore
- type MemorySession
- func (s *MemorySession) Clear()
- func (s *MemorySession) Delete(key string)
- func (s *MemorySession) Flash(key string, val any)
- func (s *MemorySession) Get(key string) any
- func (s *MemorySession) GetFlash(key string) any
- func (s *MemorySession) ID() string
- func (s *MemorySession) Set(key string, val any)
- type Middleware
- type NextHandler
- type Pipeline
- type RouteGroup
- func (g *RouteGroup) Delete(path string, handler func(ctx *Context), extra ...Middleware)
- func (g *RouteGroup) Get(path string, handler func(ctx *Context), extra ...Middleware)
- func (g *RouteGroup) Patch(path string, handler func(ctx *Context), extra ...Middleware)
- func (g *RouteGroup) Post(path string, handler func(ctx *Context), extra ...Middleware)
- func (g *RouteGroup) Put(path string, handler func(ctx *Context), extra ...Middleware)
- type Router
- func (r *Router) Delete(path string, handler func(ctx *Context), middleware ...Middleware)
- func (r *Router) Get(path string, handler func(ctx *Context), middleware ...Middleware)
- func (r *Router) GetRoutes() map[string]func(ctx *Context) error
- func (r *Router) Group(prefix string, middleware []Middleware, fn func(g *RouteGroup))
- func (r *Router) Patch(path string, handler func(ctx *Context), middleware ...Middleware)
- func (r *Router) Post(path string, handler func(ctx *Context), middleware ...Middleware)
- func (r *Router) Put(path string, handler func(ctx *Context), middleware ...Middleware)
- type Rule
- type RuleSet
- type Tempose
- type Validator
- type ViewFunc
Constants ¶
const GoStackRuntimeJS = `` /* 3539-byte string literal not displayed */
GoStackRuntimeJS holds the core client-side reactivity engine text. This is maintained as a raw string literal to compile directly into the text section of the executable, bypassing runtime disk lookups.
Variables ¶
This section is empty.
Functions ¶
func GetSession ¶
GetSession extracts the active resolved session context out of the Context values repository.
PARAMETERS:
- ctx: The active HTTP context pointer passed to your route handler.
RETURNS:
- The active contract.Session struct. Returns nil if the session middleware was not registered.
func Logger ¶
func Logger(ctx *Context, next NextHandler) error
Logger is a production-ready request logging middleware. It prints the HTTP method, path, response status code, and elapsed duration for every request that passes through it.
Usage:
router.Get("/", homeHandler, http.Logger)
// or applied globally:
router.Group("/api", []http.Middleware{http.Logger}, func(g *http.RouteGroup) { ... })
func RequireAuth ¶
func RequireAuth(ctx *Context, next NextHandler) error
RequireAuth blocks access to downstream handlers if the request session does not contain a positive "authenticated" value.
DESIGN RATIONALE: In fullstack web applications, protecting routes behind auth gates is a critical security concern. By placing this middleware early in the execution chain, we ensure unauthorized access is blocked before reaching sensitive controllers.
CONFLICT RESOLUTION: Because the current package is named 'http', the standard library 'net/http' package is imported with the alias 'netHTTP' to avoid compiler namespace collisions.
func Rules ¶
Rules reflects over src, extracts the string representation of each field named in set, and runs each Rule in the declared order. The first failing rule for each field contributes its message to the returned error map. Fields with no failures are omitted from the result.
Parameters:
- src: A pointer to the struct being validated (typically a request object).
- set: The RuleSet declaring which fields to validate and which rules to apply.
Returns a map[string]string of field → error message. An empty map means all rules passed.
Example usage inside a Validator implementation:
func (r *LoginRequest) Validate() map[string]string {
return http.Rules(r, http.RuleSet{
"Email": {http.Required, http.IsEmail},
"Password": {http.Required, http.MinLength(8)},
})
}
Types ¶
type Connection ¶
type Connection struct {
UserID string // The authenticated user this connection belongs to (optional).
// contains filtered or unexported fields
}
Connection wraps a single active WebSocket connection.
func (*Connection) Read ¶
func (c *Connection) Read()
Read pumps incoming messages from the WebSocket connection to the hub.
func (*Connection) Write ¶
func (c *Connection) Write()
Write pumps messages from the hub's send channel to the WebSocket connection.
type Context ¶
type Context struct {
// Writer is the standard library stream manager used to flush headers and payloads back to the client.
Writer http.ResponseWriter
// Request represents the incoming HTTP data payload, containing headers, cookies, URLs, and forms.
Request *http.Request
// Tempose points directly to the companion view engine, enabling isolation during server-side composition.
Tempose *Tempose
// contains filtered or unexported fields
}
Context acts as the unified "Gateway" for every single HTTP request passing through the engine. It encapsulates the raw underlying connection streams (ResponseWriter, Request) and pairs them with a direct reference to the Tempose view rendering engine.
Architectural Design Choice: By storing a direct pointer to *Tempose rather than referencing the global foundation.Container, we decouple the generic HTTP layer from the high-level application orchestrator. This eliminates recursive dependency loops (Import Cycles) and keeps the framework's packages strictly ordered.
func (*Context) JSON ¶
JSON standardizes the API response delivery pipeline. It forcefully alters the outgoing header metadata to application/json, flushes the requested HTTP status code, and serializes the target data structure directly into the raw network stream.
Parameters:
- code: The RFC-compliant HTTP status integer to commit (e.g., 200, 201, 400).
- data: The Go interface layout (struct, map, slice) to stringify into valid JSON syntax.
Returns:
- An error if the json encoder encounters unsupported types or writing blocks.
func (*Context) Locale ¶ added in v1.0.1
Locale extracts the client language preference, checking the URL query parameter and falling back to the standard HTTP Accept-Language header.
func (*Context) Post ¶
Post abstracts POST body payload and multipart form data evaluation. It reads input fields submitted by form elements or client payloads seamlessly.
Parameters:
- key: The name identifier of the form input field to extract.
Returns:
- The string data corresponding to the key, returning an empty string if omitted.
func (*Context) Query ¶
Query abstracts URL query string parameter resolution into a clean, predictable API. It fetches parameters appended directly onto the request URI string (e.g., /search?term=value).
Parameters:
- key: The query parameter name string to extract.
Returns:
- The string value matching the key. If the key does not exist, it returns an empty string "".
func (*Context) Render ¶
Render facilitates the server-side composition of HTML view templates.
Architectural Note: Because the Tempose engine is intentionally built as a "pure" compiler (relying strictly on io.Writer), the HTTP Context acts as the protocol bridge here. It explicitly commits the HTTP 200 OK status header into the response wire right before handing the stream over to the compiler pass.
Parameters:
- viewName: The logical identifier or path of the template file to execute (e.g., "home").
- data: Any arbitrary structure, struct, or map to bind dynamically inside the template bindings.
Returns:
- An error if template reading, compilation, or streaming fails.
type Engine ¶
Engine represents the operational HTTP server configuration block. It manages the template view renderer, routing tables, and server lifecycle options.
func NewEngine ¶
NewEngine establishes an operational HTTP processing core.
Parameters:
- router: An initialized routing context registry.
- tempose: A configured template view engine instance.
func (*Engine) ServeHTTP ¶
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP acts as the low-level execution entry point required by Go's standard http.Server interface. Every single inbound network connection request shifts through this method pass.
How It Works:
- It monitors incoming connection request patterns against the internal Router table.
- If a match is found, it instantiates the framework's custom Context block.
- It populates that Context with the raw response stream, the request metadata, and the Engine's direct Tempose reference.
- It dispatches execution to the controller handler seamlessly.
- If no route matches, it writes a clean RFC-standard 404 Not Found error state.
type Hub ¶
type Hub struct {
// contains filtered or unexported fields
}
Hub maintains the registry of all active connections and coordinates message delivery.
func (*Hub) BroadcastToRoom ¶ added in v1.0.1
BroadcastToRoom sends a message to all connections currently in a named room.
func (*Hub) Handler ¶
Handler returns an HTTP handler that upgrades an anonymous connection and registers it with the Hub.
func (*Hub) HandlerForUser ¶ added in v1.0.1
HandlerForUser returns an HTTP handler that upgrades the connection and registers it under the provided userID. Pass an empty string for anonymous connections.
Usage:
router.Get("/ws", func(ctx *http.Context) {
userID := ctx.Get("user_id").(string)
hub.HandlerForUser(userID).ServeHTTP(ctx.Writer, ctx.Request)
})
func (*Hub) JoinRoom ¶ added in v1.0.1
func (h *Hub) JoinRoom(room string, conn *Connection)
JoinRoom registers a connection into a named room.
func (*Hub) LeaveRoom ¶ added in v1.0.1
func (h *Hub) LeaveRoom(room string, conn *Connection)
LeaveRoom removes a connection from a named room.
type InMemoryStore ¶
type InMemoryStore struct {
// contains filtered or unexported fields
}
InMemoryStore implements the contract.SessionStore interface by keeping active sessions stored in a thread-safe map in server RAM.
WARNING: Because the data is not written to disk or shared, restarting the server processes will invalidate all active sessions, and multi-node clusters will not share session states.
func NewInMemoryStore ¶
func NewInMemoryStore() *InMemoryStore
NewInMemoryStore returns a pointer to an initialized InMemoryStore.
func (*InMemoryStore) Destroy ¶
func (store *InMemoryStore) Destroy(id string) error
Destroy invalidates and completely deletes a session record from the memory store registry.
type MemorySession ¶
type MemorySession struct {
// contains filtered or unexported fields
}
MemorySession represents an active user session stored in local server memory.
DESIGN RATIONALE: In HTTP servers, handlers execute concurrently. MemorySession uses a read-write lock (sync.RWMutex) to permit concurrent readers (e.g., loading multiple fields during rendering) while securing write actions (e.g., logging in or adding items to a basket).
func NewMemorySession ¶
func NewMemorySession(id string) *MemorySession
NewMemorySession creates a fresh instanced MemorySession with the given ID.
func (*MemorySession) Clear ¶
func (s *MemorySession) Clear()
Clear purges all state values from the session. Safe for concurrent writes.
func (*MemorySession) Delete ¶
func (s *MemorySession) Delete(key string)
Delete removes a key from the session state. Safe for concurrent writes.
func (*MemorySession) Flash ¶
func (s *MemorySession) Flash(key string, val any)
Flash stores a value in the session that will be available only on the immediately following request. On the next call to GetFlash, the value is returned and automatically removed from the session.
Typical usage — store a success notice before a redirect:
sess.Flash("success", "Your post was saved!")
http.Redirect(w, r, "/dashboard", http.StatusFound)
Then in the next request's handler:
msg := sess.GetFlash("success") // returns "Your post was saved!" and removes it
func (*MemorySession) Get ¶
func (s *MemorySession) Get(key string) any
Get retrieves a value from the session map. It is safe for concurrent reads.
func (*MemorySession) GetFlash ¶
func (s *MemorySession) GetFlash(key string) any
GetFlash retrieves a flash value set by Flash() and immediately removes it from the session so it cannot be read again on subsequent requests. Returns nil if no flash value is stored under the given key.
func (*MemorySession) ID ¶
func (s *MemorySession) ID() string
ID returns the unique session token identifier.
func (*MemorySession) Set ¶
func (s *MemorySession) Set(key string, val any)
Set commits a key-value pair to the session state. Safe for concurrent writes.
type Middleware ¶
type Middleware func(ctx *Context, next NextHandler) error
Middleware defines the strict functional contract for all GoStack interceptor layers.
DESIGN PHILOSOPHY: GoStack implements an "Onion Architecture" for middleware execution. Each layer acts as a protective shell around the controller action. By passing a 'next' callback, we allow middleware to execute logic both BEFORE and AFTER the internal request handling occurs, enabling powerful cross-cutting concerns like logging execution time, header manipulation, and response modification.
func SessionMiddleware ¶
func SessionMiddleware(store contract.SessionStore, cookieName string) Middleware
SessionMiddleware builds an HTTP middleware interceptor targeting session lifecycles.
PARAMETERS:
- store: The target contract.SessionStore instance to persist session data.
- cookieName: The identifier key string of the cookie (default: "gostack_session").
RETURNS:
- A Middleware function to hook directly into the router setup.
func Throttle ¶ added in v1.0.1
func Throttle(limit int, period time.Duration) Middleware
Throttle provisions a middleware layer implementing a thread-safe sliding window rate-limiting algorithm.
func ValidateRequest ¶
func ValidateRequest(req any) Middleware
ValidateRequest returns a Middleware that decodes the JSON request body into req's type, runs its Validate() method, and short-circuits with HTTP 422 on failure.
Parameters:
- req: A zero-value instance of the struct representing the expected JSON payload. The struct must implement Validator.
On success, the decoded and validated value is stored in the request context under the key "validated_data" for downstream handler retrieval.
Implementation note: We capture the reflect.Type at registration time and close over it in the returned middleware function. This is both safe and efficient — reflect.TypeOf is O(1) and avoids the unchecked type assertion from a sync.Map that could panic on a cache miss.
type NextHandler ¶
NextHandler represents the recursive execution gateway to the next inner layer of the onion or the final core controller action.
type Pipeline ¶
type Pipeline struct {
// contains filtered or unexported fields
}
Pipeline coordinates and executes a sequential chain of middleware layers.
ARCHITECTURAL RATIONALE:
- Decoupled Pipeline: By separating the pipeline execution from the Router, we ensure that middleware can be tested in total isolation from HTTP routing logic.
- Sequential Traversal: Unlike functional closure nesting (which creates deep, difficult-to-debug stack traces), the Pipeline uses a recursive pointer-based traversal. This maps cleanly to the expected O(n) execution order of an onion architecture.
- Short-Circuiting: Because the middleware returns an error, any layer can stop the request chain (e.g., Auth failure) by returning an error instead of invoking the 'next' gateway.
func NewPipeline ¶
func NewPipeline() *Pipeline
NewPipeline initializes an empty, ready-to-populate middleware stack.
func (*Pipeline) Run ¶
func (p *Pipeline) Run(ctx *Context, destination NextHandler) error
Run executes the middleware chain sequentially, terminating at the final destination handler (usually a controller action).
EXECUTION FLOW: It uses a recursive 'nexter' helper to build a chain of execution. Each index in the pipeline is captured by a closure, ensuring that even if multiple requests flow through the pipeline concurrently, their internal index state remains isolated on their respective call stacks.
func (*Pipeline) Through ¶
func (p *Pipeline) Through(m ...Middleware) *Pipeline
Through registers one or more middleware interceptors into the pipeline stack. Returns the pointer to the pipeline to facilitate fluent, chained configuration.
type RouteGroup ¶
type RouteGroup struct {
// contains filtered or unexported fields
}
RouteGroup holds a shared prefix and a stack of group-scoped middleware that are prepended to every route registered through the group.
func (*RouteGroup) Delete ¶
func (g *RouteGroup) Delete(path string, handler func(ctx *Context), extra ...Middleware)
Delete registers a DELETE route scoped to the group.
func (*RouteGroup) Get ¶
func (g *RouteGroup) Get(path string, handler func(ctx *Context), extra ...Middleware)
Get registers a GET route scoped to the group's prefix and middleware.
func (*RouteGroup) Patch ¶
func (g *RouteGroup) Patch(path string, handler func(ctx *Context), extra ...Middleware)
Patch registers a PATCH route scoped to the group.
func (*RouteGroup) Post ¶
func (g *RouteGroup) Post(path string, handler func(ctx *Context), extra ...Middleware)
Post registers a POST route scoped to the group.
func (*RouteGroup) Put ¶
func (g *RouteGroup) Put(path string, handler func(ctx *Context), extra ...Middleware)
Put registers a PUT route scoped to the group.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router acts as the central traffic controller for the GoStack framework.
DESIGN PHILOSOPHY: Unlike traditional static routers, the GoStack Router is "Pipeline-Aware." Every route is treated as an isolated execution unit consisting of a linear middleware onion shell and a terminal controller action.
ROUTING MECHANICS: Routes are keyed as "METHOD /path" (e.g. "GET /users", "POST /users") so the engine can dispatch by both HTTP verb and path with a single map lookup.
func NewRouter ¶
func NewRouter() *Router
NewRouter initializes a fresh, memory-isolated routing table.
func (*Router) Delete ¶
func (r *Router) Delete(path string, handler func(ctx *Context), middleware ...Middleware)
Delete registers a DELETE route.
func (*Router) Get ¶
func (r *Router) Get(path string, handler func(ctx *Context), middleware ...Middleware)
Get registers a GET route.
func (*Router) GetRoutes ¶
GetRoutes returns the raw registry table, keyed as "METHOD /path". Used by the Engine during the HTTP request lifecycle.
func (*Router) Group ¶
func (r *Router) Group(prefix string, middleware []Middleware, fn func(g *RouteGroup))
Group creates a new RouteGroup. All routes registered via the callback receive the given prefix and share the supplied middleware stack.
Example:
router.Group("/api", authMiddleware, func(g *RouteGroup) {
g.Get("/users", usersHandler)
g.Post("/users", createHandler)
})
func (*Router) Patch ¶
func (r *Router) Patch(path string, handler func(ctx *Context), middleware ...Middleware)
Patch registers a PATCH route.
type Rule ¶
Rule is a single validation function. It receives the field name and its string- coerced value, and returns whether the value is valid and an error message if not.
Example custom rule:
noSpaces := func(field, value string) (bool, string) {
if strings.Contains(value, " ") {
return false, field + " must not contain spaces"
}
return true, ""
}
var IsEmail Rule = func(field, value string) (bool, string) { pattern := `^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$` matched, _ := regexp.MatchString(pattern, value) if !matched { return false, field + " must be a valid email address" } return true, "" }
IsEmail rejects values that do not match a standard email address pattern.
Example: http.IsEmail
var IsNumeric Rule = func(field, value string) (bool, string) { matched, _ := regexp.MatchString(`^\d+$`, value) if !matched { return false, field + " must be a numeric value" } return true, "" }
IsNumeric rejects values that contain non-digit characters.
Example: http.IsNumeric
var Required Rule = func(field, value string) (bool, string) { if strings.TrimSpace(value) == "" { return false, field + " is required" } return true, "" }
Required rejects empty string values.
Example: http.Required
func IsUnique ¶
IsUnique returns a Rule that queries a database to ensure the field value is unique in the specified table and column.
func Matches ¶
Matches returns a Rule that rejects values not matching the given regular expression.
Example: http.Matches(`^[a-zA-Z]+$`)
type RuleSet ¶
RuleSet maps struct field names (as they appear in the Go struct, e.g. "Email") to an ordered slice of Rule functions to apply against that field's value.
Example:
http.RuleSet{
"Email": {http.Required, http.IsEmail},
"Password": {http.Required, http.MinLength(8)},
}
type Tempose ¶
type Tempose struct {
// contains filtered or unexported fields
}
Tempose acts as a centralized registry for all application views.
Architectural Rationale: Unlike traditional frameworks that parse disk files on every request, Tempose maintains an in-memory map of compiled functions. This registry is initialized at application boot-time, ensuring that the framework fails fast if a template is missing.
func NewTempose ¶
func NewTempose() *Tempose
NewTempose initializes the view registry. This should be called by the application's bootstrapper during the dependency injection phase.
func (*Tempose) Register ¶
Register explicitly maps a template name to a compiled ViewFunc.
Usage: This is typically invoked by generated code during the 'gostack build' process to wire up the application's view layer.
func (*Tempose) Render ¶
Render executes the requested view and writes the output to the provided io.Writer.
Architectural Note: This method is now purely focused on rendering. It does not touch HTTP status codes, keeping it decoupled and usable in any I/O context (e.g., CLI, Email, HTTP).
Returns an error if the requested view name has not been registered.
type Validator ¶
type Validator interface {
// Validate returns a map of field name → human-readable error message.
// An empty map (or nil) signals that all fields passed validation.
Validate() map[string]string
}
Validator defines the interface all request payload structs must implement to participate in the ValidateRequest middleware pipeline.
type ViewFunc ¶
ViewFunc defines the functional signature for a compiled view. In GoStack, we treat HTML templates as executable Go functions rather than interpreted strings. This provides two massive advantages:
- Compile-time safety: Any syntax error in logic is caught during the build.
- Performance: Avoiding reflection and parsing at runtime ensures O(1) dispatching, reaching parity with the world's fastest web frameworks.