http

package
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

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:

  1. ValidateRequest middleware — decodes the JSON body, invokes the Validator interface, and short- circuits with a 422 response on failure. Unchanged from the original design.
  2. 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

View Source
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

func GetSession(ctx *Context) contract.Session

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

func Rules(src any, set RuleSet) map[string]string

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) Get

func (c *Context) Get(key string) any

Get retrieves a key-value pair from the request-scoped context.

func (*Context) JSON

func (c *Context) JSON(code int, data any) error

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

func (c *Context) Locale() string

Locale extracts the client language preference, checking the URL query parameter and falling back to the standard HTTP Accept-Language header.

func (*Context) Post

func (c *Context) Post(key string) string

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

func (c *Context) Query(key string) string

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

func (c *Context) Render(viewName string, data any) error

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.

func (*Context) Set

func (c *Context) Set(key string, val any)

Set stores a key-value pair in the request-scoped context.

func (*Context) Trans added in v1.0.1

func (c *Context) Trans(key string, replace ...map[string]string) string

Trans translates a message key using the registered translator interface stored in the request context, interpolating variables.

type Engine

type Engine struct {
	Router  *Router
	Tempose *Tempose
}

Engine represents the operational HTTP server configuration block. It manages the template view renderer, routing tables, and server lifecycle options.

func NewEngine

func NewEngine(router *Router, tempose *Tempose) *Engine

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:

  1. It monitors incoming connection request patterns against the internal Router table.
  2. If a match is found, it instantiates the framework's custom Context block.
  3. It populates that Context with the raw response stream, the request metadata, and the Engine's direct Tempose reference.
  4. It dispatches execution to the controller handler seamlessly.
  5. 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 NewHub

func NewHub() *Hub

NewHub creates a new Hub instance ready to run.

func (*Hub) Broadcast

func (h *Hub) Broadcast(msg []byte)

Broadcast sends a message to ALL connected clients.

func (*Hub) BroadcastToRoom added in v1.0.1

func (h *Hub) BroadcastToRoom(room string, msg []byte)

BroadcastToRoom sends a message to all connections currently in a named room.

func (*Hub) Handler

func (h *Hub) Handler() http.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

func (h *Hub) HandlerForUser(userID string) http.Handler

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.

func (*Hub) Run

func (h *Hub) Run(ctx context.Context)

Run starts the hub's main event loop. It must be started in a goroutine before accepting connections.

func (*Hub) SendTo added in v1.0.1

func (h *Hub) SendTo(userID string, msg []byte)

SendTo delivers a message to all active connections belonging to a specific user. If the user has multiple active connections (e.g. phone + laptop), all receive the message.

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.

func (*InMemoryStore) Load

func (store *InMemoryStore) Load(id string) (contract.Session, error)

Load retrieves a session by its unique ID from the store. If the session is missing, a new session is initialized and saved.

func (*InMemoryStore) Save

func (store *InMemoryStore) Save(s contract.Session) error

Save commits the given session structure state into the 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

type NextHandler func(ctx *Context) error

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:

  1. Decoupled Pipeline: By separating the pipeline execution from the Router, we ensure that middleware can be tested in total isolation from HTTP routing logic.
  2. 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.
  3. 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

func (r *Router) GetRoutes() map[string]func(ctx *Context) error

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.

func (*Router) Post

func (r *Router) Post(path string, handler func(ctx *Context), middleware ...Middleware)

Post registers a POST route.

func (*Router) Put

func (r *Router) Put(path string, handler func(ctx *Context), middleware ...Middleware)

Put registers a PUT route.

type Rule

type Rule func(field, value string) (ok bool, message string)

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

func IsUnique(db contract.Database, table, column string) Rule

IsUnique returns a Rule that queries a database to ensure the field value is unique in the specified table and column.

func Matches

func Matches(pattern string) Rule

Matches returns a Rule that rejects values not matching the given regular expression.

Example: http.Matches(`^[a-zA-Z]+$`)

func MaxLength

func MaxLength(n int) Rule

MaxLength returns a Rule that rejects values longer than n Unicode characters.

Example: http.MaxLength(255)

func MinLength

func MinLength(n int) Rule

MinLength returns a Rule that rejects values shorter than n Unicode characters.

Example: http.MinLength(8)

type RuleSet

type RuleSet map[string][]Rule

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

func (t *Tempose) Register(name string, fn ViewFunc)

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

func (t *Tempose) Render(w io.Writer, name string, data any) error

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

type ViewFunc func(w io.Writer, data any) error

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:

  1. Compile-time safety: Any syntax error in logic is caught during the build.
  2. Performance: Avoiding reflection and parsing at runtime ensures O(1) dispatching, reaching parity with the world's fastest web frameworks.

Jump to

Keyboard shortcuts

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